Merge remote-tracking branch 'upstream/MK3' into MK3_MK404

Fix merge
This commit is contained in:
3d-gussner 2021-03-17 18:33:54 +01:00
commit 0f771b1218
53 changed files with 8814 additions and 3262 deletions

View File

@ -231,33 +231,23 @@
* SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the * 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 * compiler to calculate the worst-case usage and throw an error if the SRAM
* limit is exceeded. * 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 #define SDCARD_SORT_ALPHA //Alphabetical sorting of SD files menu
// SD Card Sorting options // 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 0.
#ifdef SDCARD_SORT_ALPHA #ifdef SDCARD_SORT_ALPHA
#define SD_SORT_TIME 0 #define SD_SORT_TIME 0
#define SD_SORT_ALPHA 1 #define SD_SORT_ALPHA 1
#define SD_SORT_NONE 2 #define SD_SORT_NONE 2
// #define SHELLSORT
// #define SORTING_DUMP
#define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256).
#define FOLDER_SORTING -1 // -1=above 0=none 1=below #define FOLDER_SORTING -1 // -1=above 0=none 1=below
#define SDSORT_GCODE 0 // Allow turning sorting on/off with LCD and M34 g-code.
#define SDSORT_USES_RAM 0 // Pre-allocate a static array for faster pre-sorting.
#define SDSORT_USES_STACK 0 // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
#define SDSORT_CACHE_NAMES 0 // Keep sorted items in RAM longer for speedy performance. Most expensive option.
#define SDSORT_DYNAMIC_RAM 0 // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
#endif #endif
#if defined(SDCARD_SORT_ALPHA) #if defined(SDCARD_SORT_ALPHA)
#define HAS_FOLDER_SORTING (FOLDER_SORTING || SDSORT_GCODE) #define HAS_FOLDER_SORTING (FOLDER_SORTING)
#endif #endif
// Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled. // Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled.

View File

@ -173,19 +173,6 @@ void dcode_3()
#include "bootapp.h" #include "bootapp.h"
#if 0 #if 0
#define FLASHSIZE 0x40000
#define RAMSIZE 0x2000
#define boot_src_addr (*((uint32_t*)(RAMSIZE - 16)))
#define boot_dst_addr (*((uint32_t*)(RAMSIZE - 12)))
#define boot_copy_size (*((uint16_t*)(RAMSIZE - 8)))
#define boot_reserved (*((uint8_t*)(RAMSIZE - 6)))
#define boot_app_flags (*((uint8_t*)(RAMSIZE - 5)))
#define boot_app_magic (*((uint32_t*)(RAMSIZE - 4)))
#define BOOT_APP_FLG_ERASE 0x01
#define BOOT_APP_FLG_COPY 0x02
#define BOOT_APP_FLG_FLASH 0x04
extern float current_temperature_pinda; extern float current_temperature_pinda;
extern float axis_steps_per_unit[NUM_AXIS]; extern float axis_steps_per_unit[NUM_AXIS];

View File

@ -766,31 +766,16 @@ static void factory_reset(char level)
#endif //FILAMENT_SENSOR #endif //FILAMENT_SENSOR
break; break;
case 3:{ // Level 3: erase everything, whole EEPROM will be set to 0xFF case 3:
lcd_puts_P(PSTR("Factory RESET")); menu_progressbar_init(EEPROM_TOP, PSTR("ERASING all data"));
lcd_puts_at_P(1, 2, PSTR("ERASING all data"));
uint16_t er_progress = 0;
lcd_set_cursor(3, 3);
lcd_space(6);
lcd_set_cursor(3, 3);
lcd_print(er_progress);
// Erase EEPROM // Erase EEPROM
for (uint16_t i = 0; i < 4096; i++) { for (uint16_t i = 0; i < EEPROM_TOP; i++) {
eeprom_update_byte((uint8_t*)i, 0xFF); eeprom_update_byte((uint8_t*)i, 0xFF);
menu_progressbar_update(i);
if (i % 41 == 0) {
er_progress++;
lcd_set_cursor(3, 3);
lcd_space(6);
lcd_set_cursor(3, 3);
lcd_print(er_progress);
lcd_puts_P(PSTR("%"));
}
} }
menu_progressbar_finish();
softReset(); softReset();
}break; break;
#ifdef SNMM #ifdef SNMM
@ -2436,38 +2421,44 @@ void refresh_cmd_timeout(void)
} }
#ifdef FWRETRACT #ifdef FWRETRACT
void retract(bool retracting, bool swapretract = false) { void retract(bool retracting, bool swapretract = false) {
// Perform FW retraction, just if needed, but behave as if the move has never took place in
// order to keep E/Z coordinates unchanged. This is done by manipulating the internal planner
// position, which requires a sync
if(retracting && !retracted[active_extruder]) { if(retracting && !retracted[active_extruder]) {
destination[X_AXIS]=current_position[X_AXIS]; st_synchronize();
destination[Y_AXIS]=current_position[Y_AXIS]; set_destination_to_current();
destination[Z_AXIS]=current_position[Z_AXIS]; current_position[E_AXIS]+=(swapretract?retract_length_swap:cs.retract_length)*float(extrudemultiply)*0.01f;
destination[E_AXIS]=current_position[E_AXIS]; plan_set_e_position(current_position[E_AXIS]);
current_position[E_AXIS]+=(swapretract?retract_length_swap:cs.retract_length)*float(extrudemultiply)*0.01f; float oldFeedrate = feedrate;
plan_set_e_position(current_position[E_AXIS]); feedrate=cs.retract_feedrate*60;
float oldFeedrate = feedrate; retracted[active_extruder]=true;
feedrate=cs.retract_feedrate*60; prepare_move();
retracted[active_extruder]=true; if(cs.retract_zlift) {
prepare_move(); st_synchronize();
current_position[Z_AXIS]-=cs.retract_zlift; current_position[Z_AXIS]-=cs.retract_zlift;
plan_set_position_curposXYZE(); plan_set_position_curposXYZE();
prepare_move(); prepare_move();
feedrate = oldFeedrate; }
feedrate = oldFeedrate;
} else if(!retracting && retracted[active_extruder]) { } else if(!retracting && retracted[active_extruder]) {
destination[X_AXIS]=current_position[X_AXIS]; st_synchronize();
destination[Y_AXIS]=current_position[Y_AXIS]; set_destination_to_current();
destination[Z_AXIS]=current_position[Z_AXIS]; float oldFeedrate = feedrate;
destination[E_AXIS]=current_position[E_AXIS]; feedrate=cs.retract_recover_feedrate*60;
current_position[Z_AXIS]+=cs.retract_zlift; if(cs.retract_zlift) {
plan_set_position_curposXYZE(); current_position[Z_AXIS]+=cs.retract_zlift;
current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(cs.retract_length+cs.retract_recover_length))*float(extrudemultiply)*0.01f; plan_set_position_curposXYZE();
plan_set_e_position(current_position[E_AXIS]); prepare_move();
float oldFeedrate = feedrate; st_synchronize();
feedrate=cs.retract_recover_feedrate*60; }
retracted[active_extruder]=false; current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(cs.retract_length+cs.retract_recover_length))*float(extrudemultiply)*0.01f;
prepare_move(); plan_set_e_position(current_position[E_AXIS]);
feedrate = oldFeedrate; retracted[active_extruder]=false;
prepare_move();
feedrate = oldFeedrate;
} }
} //retract } //retract
#endif //FWRETRACT #endif //FWRETRACT
void trace() { void trace() {
@ -4382,21 +4373,22 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow
total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100); total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
} }
#ifdef FWRETRACT
if(cs.autoretract_enabled) #ifdef FWRETRACT
if(cs.autoretract_enabled) {
if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { if( !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
float echange=destination[E_AXIS]-current_position[E_AXIS]; float echange=destination[E_AXIS]-current_position[E_AXIS];
if((echange<-MIN_RETRACT && !retracted[active_extruder]) || (echange>MIN_RETRACT && retracted[active_extruder])) { //move appears to be an attempt to retract or recover
if((echange<-MIN_RETRACT && !retracted[active_extruder]) || (echange>MIN_RETRACT && retracted[active_extruder])) { //move appears to be an attempt to retract or recover st_synchronize();
current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations current_position[E_AXIS] = destination[E_AXIS]; //hide the slicer-generated retract/recover from calculations
plan_set_e_position(current_position[E_AXIS]); //AND from the planner plan_set_e_position(current_position[E_AXIS]); //AND from the planner
retract(!retracted[active_extruder]); retract(!retracted[active_extruder]);
return; return;
} }
} }
#endif //FWRETRACT }
#endif //FWRETRACT
prepare_move(); prepare_move();
//ClearToSend(); //ClearToSend();
} }
@ -4464,9 +4456,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
lcd_update(0); lcd_update(0);
} }
break; break;
#ifdef FWRETRACT
#ifdef FWRETRACT
/*! /*!
### G10 - Retract <a href="https://reprap.org/wiki/G-code#G10:_Retract">G10: Retract</a> ### G10 - Retract <a href="https://reprap.org/wiki/G-code#G10:_Retract">G10: Retract</a>
Retracts filament according to settings of `M207` Retracts filament according to settings of `M207`
@ -4492,7 +4484,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
retract(false); retract(false);
#endif #endif
break; break;
#endif //FWRETRACT #endif //FWRETRACT
/*! /*!
@ -7317,8 +7309,9 @@ Sigma_Exit:
if(code_seen(axis_codes[i])) cs.add_homing[i] = code_value(); if(code_seen(axis_codes[i])) cs.add_homing[i] = code_value();
} }
break; break;
#ifdef FWRETRACT
#ifdef FWRETRACT
/*! /*!
### M207 - Set firmware retraction <a href="https://reprap.org/wiki/G-code#M207:_Set_retract_length">M207: Set retract length</a> ### M207 - Set firmware retraction <a href="https://reprap.org/wiki/G-code#M207:_Set_retract_length">M207: Set retract length</a>
#### Usage #### Usage
@ -7416,7 +7409,9 @@ Sigma_Exit:
} }
}break; }break;
#endif // FWRETRACT #endif // FWRETRACT
#if EXTRUDERS > 1 #if EXTRUDERS > 1
/*! /*!
@ -11262,7 +11257,7 @@ void restore_print_from_eeprom(bool mbl_was_active) {
} }
dir_name[8] = '\0'; dir_name[8] = '\0';
MYSERIAL.println(dir_name); MYSERIAL.println(dir_name);
// strcpy(dir_names[i], dir_name); // strcpy(card.dir_names[i], dir_name);
card.chdir(dir_name, false); card.chdir(dir_name, false);
} }

View File

@ -28,15 +28,6 @@ void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size)
boot_app_magic = BOOT_APP_MAGIC; boot_app_magic = BOOT_APP_MAGIC;
boot_app_flags |= BOOT_APP_FLG_COPY; boot_app_flags |= BOOT_APP_FLG_COPY;
boot_app_flags |= BOOT_APP_FLG_ERASE; boot_app_flags |= BOOT_APP_FLG_ERASE;
/* uint16_t ui; for (ui = 0; ui < size; ui++)
{
uint8_t uc = ram_array[ui+rptr];
if (pgm_read_byte(ui+fptr) & uc != uc)
{
boot_app_flags |= BOOT_APP_FLG_ERASE;
break;
}
}*/
boot_copy_size = (uint16_t)size; boot_copy_size = (uint16_t)size;
boot_src_addr = (uint32_t)rptr; boot_src_addr = (uint32_t)rptr;
boot_dst_addr = (uint32_t)fptr; boot_dst_addr = (uint32_t)fptr;

View File

@ -7,7 +7,6 @@
#define RAMSIZE 0x2000 #define RAMSIZE 0x2000
#define ram_array ((uint8_t*)(0))
#define boot_src_addr (*((uint32_t*)(RAMSIZE - 16))) #define boot_src_addr (*((uint32_t*)(RAMSIZE - 16)))
#define boot_dst_addr (*((uint32_t*)(RAMSIZE - 12))) #define boot_dst_addr (*((uint32_t*)(RAMSIZE - 12)))
#define boot_copy_size (*((uint16_t*)(RAMSIZE - 8))) #define boot_copy_size (*((uint16_t*)(RAMSIZE - 8)))

View File

@ -15,11 +15,6 @@ CardReader::CardReader()
#ifdef SDCARD_SORT_ALPHA #ifdef SDCARD_SORT_ALPHA
sort_count = 0; sort_count = 0;
#if SDSORT_GCODE
sort_alpha = true;
sort_folders = FOLDER_SORTING;
//sort_reverse = false;
#endif
#endif #endif
filesize = 0; filesize = 0;
@ -82,7 +77,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
dir_t p; dir_t p;
uint8_t cnt = 0; uint8_t cnt = 0;
// Read the next entry from a directory // Read the next entry from a directory
while (parent.readDir(p, longFilename) > 0) { for (position = parent.curPosition(); parent.readDir(p, longFilename) > 0; position = parent.curPosition()) {
if (recursionCnt > MAX_DIR_DEPTH) if (recursionCnt > MAX_DIR_DEPTH)
return; return;
else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint
@ -151,8 +146,8 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
case LS_GetFilename: case LS_GetFilename:
//SERIAL_ECHOPGM("File: "); //SERIAL_ECHOPGM("File: ");
createFilename(filename, p); createFilename(filename, p);
cluster = parent.curCluster(); // cluster = parent.curCluster();
position = parent.curPosition(); // position = parent.curPosition();
/*MYSERIAL.println(filename); /*MYSERIAL.println(filename);
SERIAL_ECHOPGM("Write date: "); SERIAL_ECHOPGM("Write date: ");
writeDate = p.lastWriteDate; writeDate = p.lastWriteDate;
@ -397,7 +392,7 @@ static const char ofNowFreshFile[] PROGMEM = "Now fresh file: ";
static const char ofFileOpened[] PROGMEM = "File opened: "; static const char ofFileOpened[] PROGMEM = "File opened: ";
static const char ofSize[] PROGMEM = " Size: "; static const char ofSize[] PROGMEM = " Size: ";
static const char ofFileSelected[] PROGMEM = "File selected"; static const char ofFileSelected[] PROGMEM = "File selected";
static const char ofSDPrinting[] PROGMEM = "SD-PRINTING "; static const char ofSDPrinting[] PROGMEM = "SD-PRINTING";
static const char ofWritingToFile[] PROGMEM = "Writing to file: "; static const char ofWritingToFile[] PROGMEM = "Writing to file: ";
void CardReader::openFileReadFilteredGcode(const char* name, bool replace_current/* = false*/){ void CardReader::openFileReadFilteredGcode(const char* name, bool replace_current/* = false*/){
@ -446,17 +441,17 @@ void CardReader::openFileReadFilteredGcode(const char* name, bool replace_curren
return; return;
if (file.openFilteredGcode(curDir, fname)) { if (file.openFilteredGcode(curDir, fname)) {
getfilename(0, fname);
filesize = file.fileSize(); filesize = file.fileSize();
SERIAL_PROTOCOLRPGM(ofFileOpened);////MSG_SD_FILE_OPENED SERIAL_PROTOCOLRPGM(ofFileOpened);////MSG_SD_FILE_OPENED
SERIAL_PROTOCOL(fname); printAbsFilenameFast();
SERIAL_PROTOCOLRPGM(ofSize);////MSG_SD_SIZE SERIAL_PROTOCOLRPGM(ofSize);////MSG_SD_SIZE
SERIAL_PROTOCOLLN(filesize); SERIAL_PROTOCOLLN(filesize);
sdpos = 0; sdpos = 0;
SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED
getfilename(0, fname); lcd_setstatuspgm(ofFileSelected);
lcd_setstatus(longFilename[0] ? longFilename : fname); scrollstuff = 0;
lcd_setstatuspgm(ofSDPrinting);
} else { } else {
SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL);
SERIAL_PROTOCOL(fname); SERIAL_PROTOCOL(fname);
@ -517,9 +512,14 @@ void CardReader::openFileWrite(const char* name)
SERIAL_PROTOCOLLN('.'); SERIAL_PROTOCOLLN('.');
} else { } else {
saving = true; saving = true;
getfilename(0, fname);
SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE
SERIAL_PROTOCOLLN(fname); printAbsFilenameFast();
lcd_setstatus(fname); SERIAL_PROTOCOLLN();
SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED
lcd_setstatuspgm(ofFileSelected);
scrollstuff = 0;
} }
} }
@ -711,6 +711,15 @@ void CardReader::getfilename_simple(uint32_t position, const char * const match/
lsDive("", *curDir, match); lsDive("", *curDir, match);
} }
void CardReader::getfilename_next(uint32_t position, const char * const match/*=NULL*/)
{
curDir = &workDir;
lsAction = LS_GetFilename;
nrFiles = 1;
curDir->seekSet(position);
lsDive("", *curDir, match);
}
uint16_t CardReader::getnrfilenames() uint16_t CardReader::getnrfilenames()
{ {
curDir=&workDir; curDir=&workDir;
@ -780,13 +789,11 @@ void CardReader::updir()
/** /**
* Get the name of a file in the current directory by sort-index * Get the name of a file in the current directory by sort-index
*/ */
void CardReader::getfilename_sorted(const uint16_t nr) { void CardReader::getfilename_sorted(const uint16_t nr, uint8_t sdSort) {
getfilename( if (nr < sort_count)
#if SDSORT_GCODE getfilename_simple(sort_positions[(sdSort == SD_SORT_ALPHA) ? (sort_count - nr - 1) : nr]);
sort_alpha && else
#endif getfilename(nr);
(nr < sort_count) ? sort_order[nr] : nr
);
} }
/** /**
@ -803,9 +810,6 @@ void CardReader::presort() {
if (sdSort == SD_SORT_NONE) return; //sd sort is turned off if (sdSort == SD_SORT_NONE) return; //sd sort is turned off
#if SDSORT_GCODE
if (!sort_alpha) return;
#endif
KEEPALIVE_STATE(IN_HANDLER); KEEPALIVE_STATE(IN_HANDLER);
// Throw away old sort index // Throw away old sort index
@ -821,177 +825,170 @@ void CardReader::presort() {
lcd_show_fullscreen_message_and_wait_P(_i("Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."));////MSG_FILE_CNT c=20 r=6 lcd_show_fullscreen_message_and_wait_P(_i("Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."));////MSG_FILE_CNT c=20 r=6
fileCnt = SDSORT_LIMIT; fileCnt = SDSORT_LIMIT;
} }
lcd_clear();
#if !SDSORT_USES_RAM
lcd_set_progress();
#endif
lcd_puts_at_P(0, 1, _i("Sorting files"));////MSG_SORTING c=20 r=1
// 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 modification_time[fileCnt];
uint16_t modification_date[fileCnt];
#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
uint32_t positions[fileCnt];
// By default re-read the names from SD for every compare // By default re-read the names from SD for every compare
// retaining only two filenames at a time. This is very // retaining only two filenames at a time. This is very
// slow but is safest and uses minimal RAM. // slow but is safest and uses minimal RAM.
char name1[LONG_FILENAME_LENGTH + 1]; char name1[LONG_FILENAME_LENGTH];
uint16_t crmod_time_bckp; uint16_t crmod_time_bckp;
uint16_t crmod_date_bckp; uint16_t crmod_date_bckp;
#if HAS_FOLDER_SORTING
uint16_t dirCnt = 0;
#endif #endif
position = 0;
if (fileCnt > 1) { if (fileCnt > 1) {
// Init sort order. // Init sort order.
uint8_t sort_order[fileCnt];
for (uint16_t i = 0; i < fileCnt; i++) { for (uint16_t i = 0; i < fileCnt; i++) {
if (!IS_SD_INSERTED) return; if (!IS_SD_INSERTED) return;
manage_heater(); manage_heater();
if (i == 0)
getfilename(0);
else
getfilename_next(position);
sort_order[i] = i; sort_order[i] = i;
positions[i] = position; sort_positions[i] = position;
getfilename(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);
modification_time[i] = crmodTime;
modification_date[i] = crmodDate;
#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 #if HAS_FOLDER_SORTING
const uint16_t bit = i & 0x07, ind = i >> 3; if (filenameIsDir) dirCnt++;
if (bit == 0) isDir[ind] = 0x00;
if (filenameIsDir) isDir[ind] |= _BV(bit);
#endif
#endif #endif
} }
#ifdef QUICKSORT #ifdef QUICKSORT
quicksort(0, fileCnt - 1); quicksort(0, fileCnt - 1);
#else //Qicksort not defined, use Bubble Sort #elif defined(SHELLSORT)
uint32_t counter = 0;
uint16_t total = 0.5*(fileCnt - 1)*(fileCnt);
// Compare names from the array or just the two buffered names #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2)
#if SDSORT_USES_RAM #define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp < crmodTime)) || (crmod_date_bckp < crmodDate))
#define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0)
#define _SORT_CMP_TIME_NODIR() (((modification_date[o1] == modification_date[o2]) && (modification_time[o1] < modification_time[o2])) || \
(modification_date[o1] < modification_date [o2]))
#else
#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2)
#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || \
(crmod_date_bckp > crmodDate))
#endif #if HAS_FOLDER_SORTING
#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
#if HAS_FOLDER_SORTING for (uint8_t runs = 0; runs < 2; runs++)
#if SDSORT_USES_RAM {
// Folder sorting needs an index and bit to test for folder-ness. //run=0: sorts all files and moves folders to the beginning
const uint8_t ind1 = o1 >> 3, bit1 = o1 & 0x07, //run=1: assumes all folders are at the beginning of the list and sorts them
ind2 = o2 >> 3, bit2 = o2 & 0x07; uint16_t sortCountFiles = 0;
#define _SORT_CMP_DIR(fs) \ if (runs == 0)
(((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \ {
? _SORT_CMP_NODIR() \ sortCountFiles = fileCnt;
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0) }
#define _SORT_CMP_TIME_DIR(fs) \ #if HAS_FOLDER_SORTING
(((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \ else
? _SORT_CMP_TIME_NODIR() \ {
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0) sortCountFiles = dirCnt;
#else }
#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) #endif
#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1))
#endif uint16_t counter = 0;
#endif uint16_t total = 0;
for (uint16_t i = sortCountFiles/2; i > 0; i /= 2) total += sortCountFiles - i; //total runs for progress bar
menu_progressbar_init(total, (runs == 0)?_i("Sorting files"):_i("Sorting folders"));
for (uint16_t gap = sortCountFiles/2; gap > 0; gap /= 2)
{
for (uint16_t i = gap; i < sortCountFiles; i++)
{
if (!IS_SD_INSERTED) return;
menu_progressbar_update(counter);
counter++;
manage_heater();
uint8_t orderBckp = sort_order[i];
getfilename_simple(sort_positions[orderBckp]);
strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
crmod_date_bckp = crmodDate;
crmod_time_bckp = crmodTime;
#if HAS_FOLDER_SORTING
bool dir1 = filenameIsDir;
#endif
uint16_t j = i;
getfilename_simple(sort_positions[sort_order[j - gap]]);
char *name2 = LONGEST_FILENAME; // use the string in-place
#if HAS_FOLDER_SORTING
while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING)))
#else
while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_NODIR():_SORT_CMP_NODIR()))
#endif
{
sort_order[j] = sort_order[j - gap];
j -= gap;
#ifdef SORTING_DUMP
for (uint16_t z = 0; z < sortCountFiles; z++)
{
printf_P(PSTR("%2u "), sort_order[z]);
}
printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp);
#endif
if (j < gap) break;
getfilename_simple(sort_positions[sort_order[j - gap]]);
name2 = LONGEST_FILENAME; // use the string in-place
}
sort_order[j] = orderBckp;
}
}
}
#else //Bubble Sort
#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2)
#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || (crmod_date_bckp > crmodDate))
#if HAS_FOLDER_SORTING
#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
uint16_t counter = 0;
menu_progressbar_init(0.5*(fileCnt - 1)*(fileCnt), _i("Sorting files"));
for (uint16_t i = fileCnt; --i;) { for (uint16_t i = fileCnt; --i;) {
if (!IS_SD_INSERTED) return; if (!IS_SD_INSERTED) return;
bool didSwap = false; bool didSwap = false;
#if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used menu_progressbar_update(counter);
int8_t percent = (counter * 100) / total;//((counter * 100) / pow((fileCnt-1),2));
for (int column = 0; column < 20; column++) {
if (column < (percent / 5))
{
lcd_putc_at(column, 2, '\x01'); //simple progress bar
}
}
counter++; counter++;
#endif
//MYSERIAL.println(int(i));
for (uint16_t j = 0; j < i; ++j) { for (uint16_t j = 0; j < i; ++j) {
if (!IS_SD_INSERTED) return; if (!IS_SD_INSERTED) return;
#ifdef SORTING_DUMP
for (uint16_t z = 0; z < fileCnt; z++)
{
printf_P(PSTR("%2u "), sort_order[z]);
}
MYSERIAL.println();
#endif
manage_heater(); manage_heater();
const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1];
// The most economical method reads names as-needed
// throughout the loop. Slow if there are many.
#if !SDSORT_USES_RAM
counter++; counter++;
getfilename_simple(positions[o1]); getfilename_simple(sort_positions[o1]);
strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
crmod_date_bckp = crmodDate; crmod_date_bckp = crmodDate;
crmod_time_bckp = crmodTime; crmod_time_bckp = crmodTime;
#if HAS_FOLDER_SORTING #if HAS_FOLDER_SORTING
bool dir1 = filenameIsDir; bool dir1 = filenameIsDir;
#endif #endif
getfilename_simple(positions[o2]); getfilename_simple(sort_positions[o2]);
char *name2 = LONGEST_FILENAME; // use the string in-place char *name2 = LONGEST_FILENAME; // use the string in-place
#endif // !SDSORT_USES_RAM
// Sort the current pair according to settings. // Sort the current pair according to settings.
if ( if (
#if HAS_FOLDER_SORTING #if HAS_FOLDER_SORTING
(sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING)) (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && !_SORT_CMP_DIR(FOLDER_SORTING))
#else #else
(sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR()) (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && !_SORT_CMP_NODIR())
#endif #endif
) )
{ {
#ifdef SORTING_DUMP
puts_P(PSTR("swap"));
#endif
sort_order[j] = o2; sort_order[j] = o2;
sort_order[j + 1] = o1; sort_order[j + 1] = o1;
didSwap = true; didSwap = true;
@ -1000,45 +997,45 @@ void CardReader::presort() {
if (!didSwap) break; if (!didSwap) break;
} //end of bubble sort loop } //end of bubble sort loop
#endif #endif
// Using RAM but not keeping names around
#if (SDSORT_USES_RAM && !SDSORT_CACHE_NAMES) #ifdef SORTING_DUMP
#if SDSORT_DYNAMIC_RAM for (uint16_t z = 0; z < fileCnt; z++)
for (uint16_t i = 0; i < fileCnt; ++i) free(sortnames[i]); printf_P(PSTR("%2u "), sort_order[z]);
#if HAS_FOLDER_SORTING SERIAL_PROTOCOLLN();
free(isDir);
#endif
#endif
#endif #endif
uint8_t sort_order_reverse_index[fileCnt];
for (uint8_t i = 0; i < fileCnt; i++)
sort_order_reverse_index[sort_order[i]] = i;
for (uint8_t i = 0; i < fileCnt; i++)
{
if (sort_order_reverse_index[i] != i)
{
uint32_t el = sort_positions[i];
uint8_t idx = sort_order_reverse_index[i];
while (idx != i)
{
uint32_t el1 = sort_positions[idx];
uint8_t idx1 = sort_order_reverse_index[idx];
sort_order_reverse_index[idx] = idx;
sort_positions[idx] = el;
idx = idx1;
el = el1;
}
sort_order_reverse_index[idx] = idx;
sort_positions[idx] = el;
}
}
menu_progressbar_finish();
} }
else { else {
sort_order[0] = 0;
#if (SDSORT_USES_RAM && SDSORT_CACHE_NAMES)
getfilename(0); getfilename(0);
#if SDSORT_DYNAMIC_RAM sort_positions[0] = position;
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; 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_putc_at(column, 2, '\x01'); //simple progress bar
}
_delay(300);
lcd_set_degree();
lcd_clear();
#endif
lcd_update(2); lcd_update(2);
KEEPALIVE_STATE(NOT_BUSY); KEEPALIVE_STATE(NOT_BUSY);
lcd_timeoutToStatus.start(); lcd_timeoutToStatus.start();
@ -1046,17 +1043,6 @@ void CardReader::presort() {
void CardReader::flush_presort() { void CardReader::flush_presort() {
if (sort_count > 0) { 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; sort_count = 0;
} }
} }

View File

@ -34,6 +34,7 @@ public:
void getfilename(uint16_t nr, const char* const match=NULL); void getfilename(uint16_t nr, const char* const match=NULL);
void getfilename_simple(uint32_t position, const char * const match = NULL); void getfilename_simple(uint32_t position, const char * const match = NULL);
void getfilename_next(uint32_t position, const char * const match = NULL);
uint16_t getnrfilenames(); uint16_t getnrfilenames();
void getAbsFilename(char *t); void getAbsFilename(char *t);
@ -53,12 +54,7 @@ public:
void swap(uint8_t left, uint8_t right); void swap(uint8_t left, uint8_t right);
void quicksort(uint8_t left, uint8_t right); void quicksort(uint8_t left, uint8_t right);
#endif //SDSORT_QUICKSORT #endif //SDSORT_QUICKSORT
void getfilename_sorted(const uint16_t nr); void getfilename_sorted(const uint16_t nr, uint8_t sdSort);
#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 #endif
FORCE_INLINE bool isFileOpen() { return file.isOpen(); } FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
@ -84,7 +80,7 @@ public:
// There are scenarios when simple modification time is not enough (on MS Windows) // There are scenarios when simple modification time is not enough (on MS Windows)
// Therefore these timestamps hold the most recent one of creation/modification date/times // Therefore these timestamps hold the most recent one of creation/modification date/times
uint16_t crmodTime, crmodDate; uint16_t crmodTime, crmodDate;
uint32_t cluster, position; uint32_t /* cluster, */ position;
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;
@ -99,45 +95,7 @@ private:
// Sort files and folders alphabetically. // Sort files and folders alphabetically.
#ifdef SDCARD_SORT_ALPHA #ifdef SDCARD_SORT_ALPHA
uint16_t sort_count; // Count of sorted items in the current directory uint16_t sort_count; // Count of sorted items in the current directory
#if SDSORT_GCODE uint32_t sort_positions[SDSORT_LIMIT];
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 modification_time[SDSORT_LIMIT];
uint16_t modification_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 #endif // SDCARD_SORT_ALPHA

View File

@ -371,12 +371,6 @@ void repeatcommand_front()
cmdbuffer_front_already_processed = true; cmdbuffer_front_already_processed = true;
} }
bool is_buffer_empty()
{
if (buflen == 0) return true;
else return false;
}
void proc_commands() { void proc_commands() {
if (buflen) if (buflen)
{ {

View File

@ -69,7 +69,6 @@ extern bool cmd_buffer_empty();
extern void enquecommand(const char *cmd, bool from_progmem = false); extern void enquecommand(const char *cmd, bool from_progmem = false);
extern void enquecommand_front(const char *cmd, bool from_progmem = false); extern void enquecommand_front(const char *cmd, bool from_progmem = false);
extern void repeatcommand_front(); extern void repeatcommand_front();
extern bool is_buffer_empty();
extern void get_command(); extern void get_command();
extern uint16_t cmdqueue_calc_sd_length(); extern uint16_t cmdqueue_calc_sd_length();

View File

@ -68,5 +68,12 @@
#define LANG_SIZE_RESERVED 0x3000 // reserved space for secondary language (12288 bytes) #define LANG_SIZE_RESERVED 0x3000 // reserved space for secondary language (12288 bytes)
//Community language support
#define COMMUNITY_LANG_NL // Community Dutch language
//#define COMMUNITY_LANG_QR // Community new language //..use this as a template and replace 'QR'
#if defined(COMMUNITY_LANG_NL) //|| defined(COMMUNITY_LANG_QR) //..use last part as a template and replace 'QR'
#define COMMUNITY_LANG_SUPPORT
#endif
#endif //_CONFIG_H #endif //_CONFIG_H

View File

@ -53,6 +53,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
- __L__ Language - __L__ Language
- __S__ Statistics - __S__ Statistics
- __P__ Shipping prep - __P__ Shipping prep
- __M__ Service/Maintenance prep
- __S/P__ Statistics and Shipping prep - __S/P__ Statistics and Shipping prep
will overwrite existing values to 0 or default. will overwrite existing values to 0 or default.
@ -157,6 +158,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| 0x0F60h 3936 | float | EEPROM_XYZ_CAL_SKEW | ??? | ff ff ff ffh | XYZ skew value | ??? | D3 Ax0f60 C4 | 0x0F60h 3936 | float | EEPROM_XYZ_CAL_SKEW | ??? | ff ff ff ffh | XYZ skew value | ??? | D3 Ax0f60 C4
| 0x0F5Fh 3935 | uint8 | EEPROM_WIZARD_ACTIVE | 01h 1 | 01h 1 __P__ | Wizard __active__ | ??? | D3 Ax0f5f C1 | 0x0F5Fh 3935 | uint8 | EEPROM_WIZARD_ACTIVE | 01h 1 | 01h 1 __P__ | Wizard __active__ | ??? | D3 Ax0f5f C1
| ^ | ^ | ^ | 00h 0 | ^ | Wizard __inactive__ | ^ | ^ | ^ | ^ | ^ | 00h 0 | ^ | Wizard __inactive__ | ^ | ^
| ^ | ^ | ^ | 02h 2 | 02h 2 __M__ | Wizard active - Z cal after shipping/service prep | ^ | ^
| 0x0F5Dh 3933 | uint16 | EEPROM_BELTSTATUS_X | ??? | ff ffh | X Beltstatus | ??? | D3 Ax0f5d C2 | 0x0F5Dh 3933 | uint16 | EEPROM_BELTSTATUS_X | ??? | ff ffh | X Beltstatus | ??? | D3 Ax0f5d C2
| 0x0F5Bh 3931 | uint16 | EEPROM_BELTSTATUS_Y | ??? | ff ffh | Y Beltstatus | ??? | D3 Ax0f5b C2 | 0x0F5Bh 3931 | uint16 | EEPROM_BELTSTATUS_Y | ??? | ff ffh | Y Beltstatus | ??? | D3 Ax0f5b C2
| 0x0F5Ah 3930 | uint8 | EEPROM_DIR_DEPTH | 00h-ffh 0-255 | ffh 255 | Directory depth | ??? | D3 Ax0f5a C1 | 0x0F5Ah 3930 | uint8 | EEPROM_DIR_DEPTH | 00h-ffh 0-255 | ffh 255 | Directory depth | ??? | D3 Ax0f5a C1

View File

@ -210,6 +210,16 @@ const char* lang_get_name_by_code(uint16_t code)
case LANG_CODE_FR: return _n("Francais"); case LANG_CODE_FR: return _n("Francais");
case LANG_CODE_IT: return _n("Italiano"); case LANG_CODE_IT: return _n("Italiano");
case LANG_CODE_PL: return _n("Polski"); case LANG_CODE_PL: return _n("Polski");
#ifdef COMMUNITY_LANG_SUPPORT //Community language support
#ifdef COMMUNITY_LANG_NL
case LANG_CODE_NL: return _n("Nederlands"); //community contribution
#endif // COMMUNITY_LANG_NL
//Use the 3 lines below as a template and replace 'QR' and 'New language'
//#ifdef COMMUNITY_LANG_QR
// case LANG_CODE_QR: return _n("New language"); //community contribution
//#endif // COMMUNITY_LANG_QR
#endif // COMMUNITY_LANG_SUPPORT
} }
return _n("??"); return _n("??");
} }

View File

@ -96,6 +96,15 @@ typedef struct
#define LANG_CODE_FR 0x6672 //!<'fr' #define LANG_CODE_FR 0x6672 //!<'fr'
#define LANG_CODE_IT 0x6974 //!<'it' #define LANG_CODE_IT 0x6974 //!<'it'
#define LANG_CODE_PL 0x706c //!<'pl' #define LANG_CODE_PL 0x706c //!<'pl'
#ifdef COMMUNITY_LANG_SUPPORT //Community language support
#ifdef COMMUNITY_LANG_NL
#define LANG_CODE_NL 0x6e6c //!<'nl'
#endif // COMMUNITY_LANG_NL
//Use the 3 lines below as a template and replace 'QR', '0X7172' and 'qr'
//#ifdef COMMUNITY_LANG_QR
//#define LANG_CODE_QR 0x7172 //!<'qr'
//#endif // COMMUNITY_LANG_QR
#endif // COMMUNITY_LANG_SUPPORT
///@} ///@}
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -963,21 +963,6 @@ void lcd_set_custom_characters_arrows(void)
lcd_createChar_P(1, lcd_chardata_arrdown); lcd_createChar_P(1, lcd_chardata_arrdown);
} }
const uint8_t lcd_chardata_progress[8] PROGMEM = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111};
void lcd_set_custom_characters_progress(void)
{
lcd_createChar_P(1, lcd_chardata_progress);
}
const uint8_t lcd_chardata_arr2down[8] PROGMEM = { const uint8_t lcd_chardata_arr2down[8] PROGMEM = {
B00000, B00000,
B00000, B00000,

View File

@ -204,7 +204,6 @@ private:
extern void lcd_set_custom_characters(void); extern void lcd_set_custom_characters(void);
extern void lcd_set_custom_characters_arrows(void); extern void lcd_set_custom_characters_arrows(void);
extern void lcd_set_custom_characters_progress(void);
extern void lcd_set_custom_characters_nextpage(void); extern void lcd_set_custom_characters_nextpage(void);
extern void lcd_set_custom_characters_degree(void); extern void lcd_set_custom_characters_degree(void);

View File

@ -34,33 +34,35 @@ uint8_t menu_top = 0;
uint8_t menu_clicked = 0; uint8_t menu_clicked = 0;
uint8_t menu_entering = 0;
uint8_t menu_leaving = 0; uint8_t menu_leaving = 0;
menu_func_t menu_menu = 0; menu_func_t menu_menu = 0;
static_assert(sizeof(menu_data)>= sizeof(menu_data_edit_t),"menu_data_edit_t doesn't fit into menu_data"); static_assert(sizeof(menu_data)>= sizeof(menu_data_edit_t),"menu_data_edit_t doesn't fit into menu_data");
void menu_data_reset(void)
{
// Resets the global shared C union.
// This ensures, that the menu entered will find out, that it shall initialize itself.
memset(&menu_data, 0, sizeof(menu_data));
}
void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state) void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state)
{ {
asm("cli"); CRITICAL_SECTION_START;
if (menu_menu != menu) if (menu_menu != menu)
{ {
menu_menu = menu; menu_menu = menu;
lcd_encoder = encoder; lcd_encoder = encoder;
menu_top = 0; //reset menu view. Needed if menu_back() is called from deep inside a menu, such as Support menu_top = 0; //reset menu view. Needed if menu_back() is called from deep inside a menu, such as Support
asm("sei"); CRITICAL_SECTION_END;
if (reset_menu_state) if (reset_menu_state)
{ menu_data_reset();
// Resets the global shared C union.
// This ensures, that the menu entered will find out, that it shall initialize itself.
memset(&menu_data, 0, sizeof(menu_data));
}
if (feedback) lcd_quick_feedback(); if (feedback) lcd_quick_feedback();
} }
else else
asm("sei"); CRITICAL_SECTION_END;
} }
void menu_start(void) void menu_start(void)
@ -551,4 +553,33 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v
template uint8_t menu_item_edit_P<int16_t*>(const char* str, int16_t *pval, int16_t min_val, int16_t max_val); template uint8_t menu_item_edit_P<int16_t*>(const char* str, int16_t *pval, int16_t min_val, int16_t max_val);
template uint8_t menu_item_edit_P<uint8_t*>(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val); template uint8_t menu_item_edit_P<uint8_t*>(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val);
#undef _menu_data static uint8_t progressbar_block_count = 0;
static uint16_t progressbar_total = 0;
void menu_progressbar_init(uint16_t total, const char* title)
{
lcd_clear();
progressbar_block_count = 0;
progressbar_total = total;
lcd_set_cursor(0, 1);
lcd_printf_P(PSTR("%-20.20S\n"), title);
}
void menu_progressbar_update(uint16_t newVal)
{
uint8_t newCnt = (newVal * LCD_WIDTH) / progressbar_total;
if (newCnt > LCD_WIDTH)
newCnt = LCD_WIDTH;
while (newCnt > progressbar_block_count)
{
lcd_print('\xFF');
progressbar_block_count++;
}
}
void menu_progressbar_finish(void)
{
progressbar_total = 1;
menu_progressbar_update(1);
_delay(300);
}

View File

@ -59,13 +59,12 @@ extern uint8_t menu_top;
extern uint8_t menu_clicked; extern uint8_t menu_clicked;
extern uint8_t menu_entering;
extern uint8_t menu_leaving; extern uint8_t menu_leaving;
//function pointer to the currently active menu //function pointer to the currently active menu
extern menu_func_t menu_menu; extern menu_func_t menu_menu;
extern void menu_data_reset(void);
extern void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state); extern void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state);
@ -151,5 +150,8 @@ extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer)
template <typename T> template <typename T>
extern uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val); extern uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val);
extern void menu_progressbar_init(uint16_t total, const char* title);
extern void menu_progressbar_update(uint16_t newVal);
extern void menu_progressbar_finish(void);
#endif //_MENU_H #endif //_MENU_H

View File

@ -21,6 +21,7 @@ const char MSG_CALIBRATE_Z_AUTO[] PROGMEM_I1 = ISTR("Calibrating Z"); ////c=20 r
const char MSG_CARD_MENU[] PROGMEM_I1 = ISTR("Print from SD"); //// const char MSG_CARD_MENU[] PROGMEM_I1 = ISTR("Print from SD"); ////
const char MSG_CHECKING_X[] PROGMEM_I1 = ISTR("Checking X axis"); ////c=20 const char MSG_CHECKING_X[] PROGMEM_I1 = ISTR("Checking X axis"); ////c=20
const char MSG_CHECKING_Y[] PROGMEM_I1 = ISTR("Checking Y axis"); ////c=20 const char MSG_CHECKING_Y[] PROGMEM_I1 = ISTR("Checking Y axis"); ////c=20
const char MSG_COMMUNITY_MADE[] PROGMEM_I1 = ISTR("Community made"); ////c=18
const char MSG_CONFIRM_NOZZLE_CLEAN[] PROGMEM_I1 = ISTR("Please clean the nozzle for calibration. Click when done."); ////c=20 r=8 const char MSG_CONFIRM_NOZZLE_CLEAN[] PROGMEM_I1 = ISTR("Please clean the nozzle for calibration. Click when done."); ////c=20 r=8
const char MSG_COOLDOWN[] PROGMEM_I1 = ISTR("Cooldown"); //// const char MSG_COOLDOWN[] PROGMEM_I1 = ISTR("Cooldown"); ////
const char MSG_CRASH[] PROGMEM_I1 = ISTR("Crash"); ////c=7 const char MSG_CRASH[] PROGMEM_I1 = ISTR("Crash"); ////c=7
@ -79,7 +80,7 @@ const char MSG_PRESS_TO_UNLOAD[] PROGMEM_I1 = ISTR("Please press the knob to unl
const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20 const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20
const char MSG_PULL_OUT_FILAMENT[] PROGMEM_I1 = ISTR("Please pull out filament immediately"); ////c=20 r=4 const char MSG_PULL_OUT_FILAMENT[] PROGMEM_I1 = ISTR("Please pull out filament immediately"); ////c=20 r=4
const char MSG_RECOVER_PRINT[] PROGMEM_I1 = ISTR("Blackout occurred. Recover print?"); ////c=20 r=2 const char MSG_RECOVER_PRINT[] PROGMEM_I1 = ISTR("Blackout occurred. Recover print?"); ////c=20 r=2
const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\xF8" "Refresh"); //// const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\x04" "Refresh"); ////
const char MSG_REMOVE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please remove steel sheet from heatbed."); ////c=20 r=4 const char MSG_REMOVE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please remove steel sheet from heatbed."); ////c=20 r=4
const char MSG_RESET[] PROGMEM_I1 = ISTR("Reset"); ////c=14 const char MSG_RESET[] PROGMEM_I1 = ISTR("Reset"); ////c=14
const char MSG_RESUME_PRINT[] PROGMEM_I1 = ISTR("Resume print"); ////c=18 const char MSG_RESUME_PRINT[] PROGMEM_I1 = ISTR("Resume print"); ////c=18
@ -202,4 +203,3 @@ const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20
const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13 const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13
const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20 const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20
const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed"; const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed";
const char MSG_FILE_SELECTED[] PROGMEM_N1 = "File selected"; ////c=20

View File

@ -22,6 +22,7 @@ extern const char MSG_CALIBRATE_Z_AUTO[];
extern const char MSG_CARD_MENU[]; extern const char MSG_CARD_MENU[];
extern const char MSG_CHECKING_X[]; extern const char MSG_CHECKING_X[];
extern const char MSG_CHECKING_Y[]; extern const char MSG_CHECKING_Y[];
extern const char MSG_COMMUNITY_MADE[];
extern const char MSG_CONFIRM_NOZZLE_CLEAN[]; extern const char MSG_CONFIRM_NOZZLE_CLEAN[];
extern const char MSG_COOLDOWN[]; extern const char MSG_COOLDOWN[];
extern const char MSG_CRASH[]; extern const char MSG_CRASH[];
@ -202,7 +203,6 @@ extern const char MSG_M112_KILL[];
extern const char MSG_ADVANCE_K[]; extern const char MSG_ADVANCE_K[];
extern const char MSG_POWERPANIC_DETECTED[]; extern const char MSG_POWERPANIC_DETECTED[];
extern const char MSG_LCD_STATUS_CHANGED[]; extern const char MSG_LCD_STATUS_CHANGED[];
extern const char MSG_FILE_SELECTED[];
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@ -15,19 +15,6 @@
static unsigned const int __attribute__((section(".version"))) static unsigned const int __attribute__((section(".version")))
optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
/* Watchdog settings */
#define WATCHDOG_OFF (0)
#define WATCHDOG_16MS (_BV(WDE))
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
#if 0 #if 0
#define W25X20CL_SIGNATURE_0 9 #define W25X20CL_SIGNATURE_0 9
#define W25X20CL_SIGNATURE_1 8 #define W25X20CL_SIGNATURE_1 8
@ -39,13 +26,6 @@ static unsigned const int __attribute__((section(".version")))
#define W25X20CL_SIGNATURE_2 0x01 #define W25X20CL_SIGNATURE_2 0x01
#endif #endif
static void watchdogConfig(uint8_t x) {
CRITICAL_SECTION_START
WDTCSR = _BV(WDCE) | _BV(WDE);
WDTCSR = x;
CRITICAL_SECTION_END
}
#define RECV_READY ((UCSR0A & _BV(RXC0)) != 0) #define RECV_READY ((UCSR0A & _BV(RXC0)) != 0)
static uint8_t getch(void) { static uint8_t getch(void) {
@ -74,7 +54,7 @@ static void putch(char ch) {
static void verifySpace() { static void verifySpace() {
if (getch() != CRC_EOP) { if (getch() != CRC_EOP) {
putch(STK_FAILED); putch(STK_FAILED);
watchdogConfig(WATCHDOG_16MS); // shorten WD timeout wdt_enable(WDTO_15MS); // shorten WD timeout
while (1) // and busy-loop so that WD causes while (1) // and busy-loop so that WD causes
; // a reset and app start. ; // a reset and app start.
} }
@ -100,7 +80,10 @@ extern struct block_t *block_buffer;
//! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup() //! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup()
uint8_t optiboot_w25x20cl_enter() uint8_t optiboot_w25x20cl_enter()
{ {
if (boot_app_flags & BOOT_APP_FLG_USER0) return 1; // Make sure to check boot_app_magic as well. Since these bootapp flags are located right in the middle of the stack,
// they can be unintentionally changed. As a workaround to the language upload problem, do not only check for one bit if it's set,
// but rather test 33 bits for the correct value before exiting optiboot early.
if ((boot_app_magic == BOOT_APP_MAGIC) && (boot_app_flags & BOOT_APP_FLG_USER0)) return 1;
uint8_t ch; uint8_t ch;
uint8_t rampz = 0; uint8_t rampz = 0;
register uint16_t address = 0; register uint16_t address = 0;
@ -115,8 +98,6 @@ uint8_t optiboot_w25x20cl_enter()
// If the magic is not received on time, or it is not received correctly, continue to the application. // If the magic is not received on time, or it is not received correctly, continue to the application.
{ {
wdt_reset(); wdt_reset();
unsigned long boot_timeout = 2000000;
unsigned long boot_timer = 0;
const char *ptr = entry_magic_send; const char *ptr = entry_magic_send;
const char *end = strlen_P(entry_magic_send) + ptr; const char *end = strlen_P(entry_magic_send) + ptr;
const uint8_t selectedSerialPort_bak = selectedSerialPort; const uint8_t selectedSerialPort_bak = selectedSerialPort;
@ -138,11 +119,17 @@ uint8_t optiboot_w25x20cl_enter()
ptr = entry_magic_receive; ptr = entry_magic_receive;
end = strlen_P(entry_magic_receive) + ptr; end = strlen_P(entry_magic_receive) + ptr;
while (ptr != end) { while (ptr != end) {
while (rx_buffer.head == SerialHead) { unsigned long boot_timer = 2000000;
// Beware of this volatile pointer - it is important since the while-cycle below
// doesn't contain any obvious references to rx_buffer.head
// thus the compiler is allowed to remove the check from the cycle
// i.e. rx_buffer.head == SerialHead would not be checked at all!
// With the volatile keyword the compiler generates exactly the same code as without it with only one difference:
// the last brne instruction jumps onto the (*rx_head == SerialHead) check and NOT onto the wdr instruction bypassing the check.
volatile int *rx_head = &rx_buffer.head;
while (*rx_head == SerialHead) {
wdt_reset(); wdt_reset();
delayMicroseconds(1); if ( --boot_timer == 0) {
if (++ boot_timer > boot_timeout)
{
// Timeout expired, continue with the application. // Timeout expired, continue with the application.
selectedSerialPort = selectedSerialPort_bak; //revert Serial setting selectedSerialPort = selectedSerialPort_bak; //revert Serial setting
return 0; return 0;
@ -161,13 +148,14 @@ uint8_t optiboot_w25x20cl_enter()
cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt
// Send the cfm magic string. // Send the cfm magic string.
ptr = entry_magic_cfm; ptr = entry_magic_cfm;
end = strlen_P(entry_magic_cfm) + ptr;
while (ptr != end) while (ptr != end)
putch(pgm_read_byte(ptr ++)); putch(pgm_read_byte(ptr ++));
} }
spi_init(); spi_init();
w25x20cl_init(); w25x20cl_init();
watchdogConfig(WATCHDOG_OFF); wdt_disable();
/* Forever loop: exits by causing WDT reset */ /* Forever loop: exits by causing WDT reset */
for (;;) { for (;;) {
@ -306,7 +294,7 @@ uint8_t optiboot_w25x20cl_enter()
} }
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
// Adaboot no-wait mod // Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS); wdt_enable(WDTO_15MS);
verifySpace(); verifySpace();
} }
else { else {

View File

@ -55,8 +55,6 @@
#endif #endif
int scrollstuff = 0;
char longFilenameOLD[LONG_FILENAME_LENGTH];
int clock_interval = 0; int clock_interval = 0;
static void lcd_sd_updir(); static void lcd_sd_updir();
@ -64,7 +62,7 @@ static void lcd_mesh_bed_leveling_settings();
static void lcd_backlight_menu(); static void lcd_backlight_menu();
int8_t ReInitLCD = 0; int8_t ReInitLCD = 0;
uint8_t scrollstuff = 0;
int8_t SilentModeMenu = SILENT_MODE_OFF; int8_t SilentModeMenu = SILENT_MODE_OFF;
uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode
@ -326,113 +324,31 @@ bool bSettings; // flag (i.e. 'fake parameter'
const char STR_SEPARATOR[] PROGMEM = "------------"; const char STR_SEPARATOR[] PROGMEM = "------------";
static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename)
static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename)
{
char c;
int enc_dif = lcd_encoder_diff / ENCODER_PULSES_PER_STEP;
uint8_t n = LCD_WIDTH - 1;
for(uint_least8_t g = 0; g<4;g++){
lcd_putc_at(0, g, ' ');
}
lcd_putc_at(0, row, '>');
if (longFilename[0] == '\0')
{
longFilename = filename;
}
int i = 1;
int j = 0;
char* longFilenameTMP = longFilename;
while((c = *longFilenameTMP) != '\0')
{
lcd_set_cursor(i, row);
lcd_print(c);
i++;
longFilenameTMP++;
if(i==LCD_WIDTH){
i=1;
j++;
longFilenameTMP = longFilename + j;
n = LCD_WIDTH - 1;
for(int g = 0; g<300 ;g++){
manage_heater();
if(LCD_CLICKED || ( enc_dif != (lcd_encoder_diff / ENCODER_PULSES_PER_STEP))){
longFilenameTMP = longFilename;
*(longFilenameTMP + LCD_WIDTH - 2) = '\0';
i = 1;
j = 0;
break;
}else{
if (j == 1) _delay_ms(3); //wait around 1.2 s to start scrolling text
_delay_ms(1); //then scroll with redrawing every 300 ms
}
}
}
}
if(c!='\0'){
lcd_putc_at(i, row, c);
i++;
}
n=n-i+1;
lcd_space(n);
}
static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* filename, char* longFilename)
{ {
char c; char c;
uint8_t n = LCD_WIDTH - 1; uint8_t n = LCD_WIDTH - 1;
lcd_putc_at(0, row, ' '); lcd_set_cursor(0, row);
if (longFilename[0] != '\0') lcd_print((lcd_encoder == menu_item)?'>':' ');
{ while( ((c = *longFilename) != '\0') && (n>0) )
filename = longFilename;
longFilename[LCD_WIDTH-1] = '\0';
}
while( ((c = *filename) != '\0') && (n>0) )
{ {
lcd_print(c); lcd_print(c);
filename++; longFilename++;
n--; n--;
} }
lcd_space(n); lcd_space(n);
} }
static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* filename, char* longFilename) static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* longFilename)
{ {
char c; char c;
uint8_t n = LCD_WIDTH - 2; uint8_t n = LCD_WIDTH - 2;
lcd_putc_at(0, row, '>'); lcd_set_cursor(0, row);
lcd_print(LCD_STR_FOLDER[0]); lcd_print((lcd_encoder == menu_item)?'>':' ');
if (longFilename[0] != '\0') lcd_print(LCD_STR_FOLDER[0]);
{ while( ((c = *longFilename) != '\0') && (n>0) )
filename = longFilename;
longFilename[LCD_WIDTH-2] = '\0';
}
while( ((c = *filename) != '\0') && (n>0) )
{ {
lcd_print(c); lcd_print(c);
filename++; longFilename++;
n--;
}
lcd_space(n);
}
static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* filename, char* longFilename)
{
char c;
uint8_t n = LCD_WIDTH - 2;
lcd_putc_at(0, row, ' ');
lcd_print(LCD_STR_FOLDER[0]);
if (longFilename[0] != '\0')
{
filename = longFilename;
longFilename[LCD_WIDTH-2] = '\0';
}
while( ((c = *filename) != '\0') && (n>0) )
{
lcd_print(c);
filename++;
n--; n--;
} }
lcd_space(n); lcd_space(n);
@ -441,48 +357,16 @@ static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* fil
#define MENU_ITEM_SDDIR(str_fn, str_fnl) do { if (menu_item_sddir(str_fn, str_fnl)) return; } while (0) #define MENU_ITEM_SDDIR(str_fn, str_fnl) do { if (menu_item_sddir(str_fn, str_fnl)) return; } while (0)
//#define MENU_ITEM_SDDIR(str, str_fn, str_fnl) MENU_ITEM(sddirectory, str, str_fn, str_fnl) #define MENU_ITEM_SDFILE(str_fn, str_fnl) do { if (menu_item_sdfile(str_fn, str_fnl)) return; } while (0)
//extern uint8_t menu_item_sddir(const char* str, const char* str_fn, char* str_fnl);
#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) do { if (menu_item_sdfile(str, str_fn, str_fnl)) return; } while (0)
//#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) MENU_ITEM(sdfile, str, str_fn, str_fnl)
//extern uint8_t menu_item_sdfile(const char* str, const char* str_fn, char* str_fnl);
uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) uint8_t menu_item_sddir(const char* str_fn, char* str_fnl)
{ {
#ifdef NEW_SD_MENU
// str_fnl[18] = 0;
// printf_P(PSTR("menu dir %d '%s' '%s'\n"), menu_row, str_fn, str_fnl);
if (menu_item == menu_line) if (menu_item == menu_line)
{ {
if (lcd_draw_update) if (lcd_draw_update)
{ {
lcd_set_cursor(0, menu_row); lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl);
int cnt = lcd_printf_P(PSTR("%c%c%-18s"), (lcd_encoder == menu_item)?'>':' ', LCD_STR_FOLDER[0], str_fnl[0]?str_fnl:str_fn);
// int cnt = lcd_printf_P(PSTR("%c%c%-18s"), (lcd_encoder == menu_item)?'>':' ', LCD_STR_FOLDER[0], str_fn);
}
if (menu_clicked && (lcd_encoder == menu_item))
{
uint8_t depth = (uint8_t)card.getWorkDirDepth();
strcpy(dir_names[depth], str_fn);
// printf_P(PSTR("%s\n"), dir_names[depth]);
card.chdir(str_fn);
lcd_encoder = 0;
return menu_item_ret();
}
}
menu_item++;
return 0;
#else //NEW_SD_MENU
if (menu_item == menu_line)
{
if (lcd_draw_update)
{
if (lcd_encoder == menu_item)
lcd_implementation_drawmenu_sddirectory_selected(menu_row, str_fn, str_fnl);
else
lcd_implementation_drawmenu_sddirectory(menu_row, str_fn, str_fnl);
} }
if (menu_clicked && (lcd_encoder == menu_item)) if (menu_clicked && (lcd_encoder == menu_item))
{ {
@ -490,80 +374,32 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl)
lcd_update_enabled = 0; lcd_update_enabled = 0;
menu_action_sddirectory(str_fn); menu_action_sddirectory(str_fn);
lcd_update_enabled = 1; lcd_update_enabled = 1;
return menu_item_ret(); /* return */ menu_item_ret();
return 1;
} }
} }
menu_item++; menu_item++;
return 0; return 0;
#endif //NEW_SD_MENU
} }
static uint8_t menu_item_sdfile(const char* static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl)
#ifdef NEW_SD_MENU
str
#endif //NEW_SD_MENU
,const char* str_fn, char* str_fnl)
{ {
#ifdef NEW_SD_MENU
// printf_P(PSTR("menu sdfile\n"));
// str_fnl[19] = 0;
// printf_P(PSTR("menu file %d '%s' '%s'\n"), menu_row, str_fn, str_fnl);
if (menu_item == menu_line) if (menu_item == menu_line)
{ {
if (lcd_draw_update) if (lcd_draw_update)
{ {
// printf_P(PSTR("menu file %d %d '%s'\n"), menu_row, menuData.sdcard_menu.viewState, str_fnl[0]?str_fnl:str_fn); lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl);
lcd_set_cursor(0, menu_row);
/* if (lcd_encoder == menu_item)
{
lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1);
if (menuData.sdcard_menu.viewState == 0)
{
menuData.sdcard_menu.viewState++;
lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1);
}
else if (menuData.sdcard_menu.viewState == 1)
{
lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 2);
}
}
else*/
{
str_fnl[19] = 0;
lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', str_fnl[0]?str_fnl:str_fn);
}
// int cnt = lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', str_fnl);
// int cnt = lcd_printf_P(PSTR("%cTESTIK.gcode"), (lcd_encoder == menu_item)?'>':' ');
} }
if (menu_clicked && (lcd_encoder == menu_item)) if (menu_clicked && (lcd_encoder == menu_item))
{ {
return menu_item_ret(); lcd_consume_click();
}
}
menu_item++;
return 0;
#else //NEW_SD_MENU
if (menu_item == menu_line)
{
if (lcd_draw_update)
{
if (lcd_encoder == menu_item)
lcd_implementation_drawmenu_sdfile_selected(menu_row, str_fn, str_fnl);
else
lcd_implementation_drawmenu_sdfile(menu_row, str_fn, str_fnl);
}
if (menu_clicked && (lcd_encoder == menu_item))
{
lcd_consume_click();
menu_action_sdfile(str_fn); menu_action_sdfile(str_fn);
return menu_item_ret(); /* return */ menu_item_ret();
return 1;
} }
} }
menu_item++; menu_item++;
return 0; return 0;
#endif //NEW_SD_MENU
} }
// Print temperature (nozzle/bed) (9 chars total) // Print temperature (nozzle/bed) (9 chars total)
@ -735,14 +571,6 @@ void lcdui_print_time(void)
//! @Brief Print status line on status screen //! @Brief Print status line on status screen
void lcdui_print_status_line(void) void lcdui_print_status_line(void)
{ {
if (IS_SD_PRINTING) {
if (strcmp(longFilenameOLD, (card.longFilename[0] ? card.longFilename : card.filename)) != 0) {
memset(longFilenameOLD, '\0', strlen(longFilenameOLD));
sprintf_P(longFilenameOLD, PSTR("%s"), (card.longFilename[0] ? card.longFilename : card.filename));
scrollstuff = 0;
}
}
if (heating_status) { // If heating flag, show progress of heating if (heating_status) { // If heating flag, show progress of heating
heating_status_counter++; heating_status_counter++;
if (heating_status_counter > 13) { if (heating_status_counter > 13) {
@ -776,6 +604,7 @@ void lcdui_print_status_line(void)
} }
} }
else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status)) { // If printing from SD, show what we are printing else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status)) { // If printing from SD, show what we are printing
const char* longFilenameOLD = (card.longFilename[0] ? card.longFilename : card.filename);
if(strlen(longFilenameOLD) > LCD_WIDTH) { if(strlen(longFilenameOLD) > LCD_WIDTH) {
int inters = 0; int inters = 0;
int gh = scrollstuff; int gh = scrollstuff;
@ -4196,7 +4025,7 @@ static void prusa_stat_printinfo()
SERIAL_ECHOPGM("][FEM:"); SERIAL_ECHOPGM("][FEM:");
SERIAL_ECHO(itostr3(feedmultiply)); SERIAL_ECHO(itostr3(feedmultiply));
SERIAL_ECHOPGM("][FNM:"); SERIAL_ECHOPGM("][FNM:");
SERIAL_ECHO(longFilenameOLD); SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename);
SERIAL_ECHOPGM("][TIM:"); SERIAL_ECHOPGM("][TIM:");
if (starttime != 0) if (starttime != 0)
{ {
@ -4511,17 +4340,10 @@ static void lcd_fsensor_state_set()
} }
#endif //FILAMENT_SENSOR #endif //FILAMENT_SENSOR
#if !SDSORT_USES_RAM
void lcd_set_degree() { void lcd_set_degree() {
lcd_set_custom_characters_degree(); lcd_set_custom_characters_degree();
} }
void lcd_set_progress() {
lcd_set_custom_characters_progress();
}
#endif
#if (LANG_MODE != 0) #if (LANG_MODE != 0)
void menu_setlang(unsigned char lang) void menu_setlang(unsigned char lang)
@ -4538,6 +4360,26 @@ void menu_setlang(unsigned char lang)
} }
} }
#ifdef COMMUNITY_LANG_SUPPORT
#ifdef W25X20CL
static void lcd_community_language_menu()
{
MENU_BEGIN();
uint8_t cnt = lang_get_count();
MENU_ITEM_BACK_P(_i("Select language")); //Back to previous Menu
for (int i = 8; i < cnt; i++) //all community languages
if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i))))
{
menu_setlang(i);
return;
}
MENU_END();
}
#endif //W25X20CL
#endif //COMMUNITY_LANG_SUPPORT && W52X20CL
static void lcd_language_menu() static void lcd_language_menu()
{ {
MENU_BEGIN(); MENU_BEGIN();
@ -4558,7 +4400,7 @@ static void lcd_language_menu()
} }
} }
else else
for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select (MK3) for (int i = 2; i < 8; i++) //skip seconday language - solved in lang_select (MK3) 'i < 8' for 7 official languages
#else //W25X20CL #else //W25X20CL
for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25) for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
#endif //W25X20CL #endif //W25X20CL
@ -4567,6 +4409,13 @@ static void lcd_language_menu()
menu_setlang(i); menu_setlang(i);
return; return;
} }
#ifdef COMMUNITY_LANG_SUPPORT
#ifdef W25X20CL
MENU_ITEM_SUBMENU_P(_T(MSG_COMMUNITY_MADE), lcd_community_language_menu); ////MSG_COMMUNITY_MADE c=18
#endif //W25X20CL
#endif //COMMUNITY_LANG_SUPPORT && W52X20CL
MENU_END(); MENU_END();
} }
#endif //(LANG_MODE != 0) #endif //(LANG_MODE != 0)
@ -4984,10 +4833,10 @@ void lcd_wizard(WizState state)
saved_printing = false; saved_printing = false;
if( eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)==2){ if( eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)==2){
lcd_show_fullscreen_message_and_wait_P(MSG_WIZARD_WELCOME_SHIPPING); lcd_show_fullscreen_message_and_wait_P(_T(MSG_WIZARD_WELCOME_SHIPPING));
state = S::Restore; state = S::Restore;
} else { } else {
wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(MSG_WIZARD_WELCOME, false, true); wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_T(MSG_WIZARD_WELCOME), false, true);
if (wizard_event) { if (wizard_event) {
state = S::Restore; state = S::Restore;
eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1); eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
@ -7139,17 +6988,25 @@ static void lcd_control_temperature_menu()
} }
#if SDCARDDETECT == -1
static void lcd_sd_refresh() static void lcd_sd_refresh()
{ {
#if SDCARDDETECT == -1
card.initsd(); card.initsd();
menu_top = 0; #else
} card.presort();
#endif #endif
menu_top = 0;
lcd_encoder = 0;
menu_data_reset(); //Forces reloading of cached variables.
}
static void lcd_sd_updir() static void lcd_sd_updir()
{ {
card.updir(); card.updir();
menu_top = 0; menu_top = 0;
lcd_encoder = 0;
menu_data_reset(); //Forces reloading of cached variables.
} }
void lcd_print_stop() void lcd_print_stop()
@ -7245,57 +7102,156 @@ void lcd_sdcard_stop()
void lcd_sdcard_menu() void lcd_sdcard_menu()
{ {
uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); enum menuState_t : uint8_t {_uninitialized, _standard, _scrolling};
typedef struct
{
menuState_t menuState = _uninitialized;
uint8_t offset;
bool isDir;
const char* scrollPointer;
uint16_t selectedFileID;
uint16_t fileCnt;
int8_t row;
uint8_t sdSort;
ShortTimer lcd_scrollTimer;
} _menu_data_sdcard_t;
static_assert(sizeof(menu_data)>= sizeof(_menu_data_sdcard_t),"_menu_data_sdcard_t doesn't fit into menu_data");
_menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]);
if (card.presort_flag == true) { switch(_md->menuState)
card.presort_flag = false; {
card.presort(); case _uninitialized: //Initialize menu data
} {
if (lcd_draw_update == 0 && LCD_CLICKED == 0) if (card.presort_flag == true) //used to force resorting if sorting type is changed.
//_delay(100); {
return; // nothing to do (so don't thrash the SD card) card.presort_flag = false;
uint16_t fileCnt = card.getnrfilenames(); card.presort();
}
_md->fileCnt = card.getnrfilenames();
_md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT);
_md->menuState = _standard;
// FALLTHRU
}
case _standard: //normal menu structure.
{
if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen.
{
_md->lcd_scrollTimer.start();
lcd_draw_update = 1;
}
if (_md->lcd_scrollTimer.expired(500) && (_md->row != -1)) //switch to the scrolling state on timeout if a file/dir is selected.
{
_md->menuState = _scrolling;
_md->offset = 0;
_md->scrollPointer = NULL;
_md->lcd_scrollTimer.start();
lcd_draw_update = 1; //forces last load before switching to scrolling.
}
if (lcd_draw_update == 0 && !LCD_CLICKED)
return; // nothing to do (so don't thrash the SD card)
_md->row = -1; // assume that no SD file/dir is currently selected. Once they are rendered, it will be changed to the correct row for the _scrolling state.
MENU_BEGIN(); //if we reached this point it means that the encoder moved or clicked or the state is being switched. Reset the scrollTimer.
MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion _md->lcd_scrollTimer.start();
card.getWorkDirName();
if (card.filename[0] == '/') MENU_BEGIN();
{ MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion
card.getWorkDirName();
if (card.filename[0] == '/')
{
#if SDCARDDETECT == -1 #if SDCARDDETECT == -1
MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh);
#else
if (card.ToshibaFlashAir_isEnabled())
MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); //show the refresh option if in flashAir mode.
#endif #endif
} else { }
MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); else
} MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir.
for (uint16_t i = 0; i < fileCnt; i++) for (uint16_t i = _md->fileCnt; i-- > 0;) // Every file, from top to bottom.
{ {
if (menu_item == menu_line) if (menu_item == menu_line) //If the file is on the screen.
{ {
const uint16_t nr = ((sdSort == SD_SORT_NONE) || farm_mode || (sdSort == SD_SORT_TIME)) ? (fileCnt - 1 - i) : i; //load filename to memory.
/*#ifdef SDCARD_RATHERRECENTFIRST #ifdef SDCARD_SORT_ALPHA
#ifndef SDCARD_SORT_ALPHA if (_md->sdSort == SD_SORT_NONE)
fileCnt - 1 - card.getfilename(i);
#endif else
#endif card.getfilename_sorted(i, _md->sdSort);
i;*/ #else
#ifdef SDCARD_SORT_ALPHA card.getfilename(i);
if (sdSort == SD_SORT_NONE) card.getfilename(nr); #endif
else card.getfilename_sorted(nr); if (lcd_encoder == menu_item) //If the file is selected.
#else {
card.getfilename(nr);
#endif
if (card.filenameIsDir) _md->selectedFileID = i;
MENU_ITEM_SDDIR(card.filename, card.longFilename); _md->isDir = card.filenameIsDir;
else _md->row = menu_row;
MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, card.longFilename); }
} else { if (card.filenameIsDir)
MENU_ITEM_DUMMY(); MENU_ITEM_SDDIR(card.filename, card.longFilename);
} else
} MENU_ITEM_SDFILE(card.filename, card.longFilename);
MENU_END(); }
else MENU_ITEM_DUMMY(); //dummy item that just increments the internal menu counters.
}
MENU_END();
} break;
case _scrolling: //scrolling filename
{
const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to _standard state.
if (_md->scrollPointer == NULL)
{
//load filename to memory.
#ifdef SDCARD_SORT_ALPHA
if (_md->sdSort == SD_SORT_NONE)
card.getfilename(_md->selectedFileID);
else
card.getfilename_sorted(_md->selectedFileID, _md->sdSort);
#else
card.getfilename(_md->selectedFileID);
#endif
_md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename;
}
if (rewindFlag == 1)
_md->offset = 0; //redraw once again from the beginning.
if (_md->lcd_scrollTimer.expired(300) || rewindFlag)
{
uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1);
lcd_set_cursor(0, _md->row);
lcd_print('>');
if (_md->isDir)
lcd_print(LCD_STR_FOLDER[0]);
for (; i != 0; i--)
{
const char* c = (_md->scrollPointer + _md->offset + ((LCD_WIDTH - ((_md->isDir)?2:1)) - i));
lcd_print(c[0]);
if (c[1])
_md->lcd_scrollTimer.start();
else
{
_md->lcd_scrollTimer.stop();
break; //stop at the end of the string
}
}
if (i != 0) //adds spaces if string is incomplete or at the end (instead of null).
{
lcd_space(i);
}
_md->offset++;
}
if (rewindFlag) //go back to sd_menu.
{
_md->lcd_scrollTimer.stop(); //forces redraw in _standard state
_md->menuState = _standard;
}
} break;
default: _md->menuState = _uninitialized; //shouldn't ever happen. Anyways, initialize the menu.
}
} }
#ifdef TMC2130 #ifdef TMC2130
static void lcd_belttest_v() static void lcd_belttest_v()
@ -8550,7 +8506,6 @@ static bool check_file(const char* filename) {
const uint32_t filesize = card.getFileSize(); const uint32_t filesize = card.getFileSize();
uint32_t startPos = 0; uint32_t startPos = 0;
const uint16_t bytesToCheck = min(END_FILE_SECTION, filesize); const uint16_t bytesToCheck = min(END_FILE_SECTION, filesize);
uint8_t blocksPrinted = 0;
if (filesize > END_FILE_SECTION) { if (filesize > END_FILE_SECTION) {
startPos = filesize - END_FILE_SECTION; startPos = filesize - END_FILE_SECTION;
card.setIndex(startPos); card.setIndex(startPos);
@ -8558,22 +8513,15 @@ static bool check_file(const char* filename) {
cmdqueue_reset(); cmdqueue_reset();
cmdqueue_serial_disabled = true; cmdqueue_serial_disabled = true;
lcd_clear(); menu_progressbar_init(bytesToCheck, _i("Checking file"));
lcd_puts_at_P(0, 1, _i("Checking file"));////c=20 r=1
lcd_set_cursor(0, 2);
while (!card.eof() && !result) { while (!card.eof() && !result) {
for (; blocksPrinted < (((card.get_sdpos() - startPos) * LCD_WIDTH) / bytesToCheck); blocksPrinted++) menu_progressbar_update(card.get_sdpos() - startPos);
lcd_print('\xFF'); //simple progress bar
card.sdprinting = true; card.sdprinting = true;
get_command(); get_command();
result = check_commands(); result = check_commands();
} }
for (; blocksPrinted < LCD_WIDTH; blocksPrinted++) menu_progressbar_finish();
lcd_print('\xFF'); //simple progress bar
_delay(100); //for the user to see the end of the progress bar.
cmdqueue_serial_disabled = false; cmdqueue_serial_disabled = false;
card.printingHasFinished(); card.printingHasFinished();
@ -8632,6 +8580,7 @@ void menu_action_sddirectory(const char* filename)
{ {
card.chdir(filename, true); card.chdir(filename, true);
lcd_encoder = 0; lcd_encoder = 0;
menu_data_reset(); //Forces reloading of cached variables.
} }
/** LCD API **/ /** LCD API **/
@ -8696,7 +8645,6 @@ static void lcd_connect_printer() {
int i = 0; int i = 0;
int t = 0; int t = 0;
lcd_set_custom_characters_progress();
lcd_puts_at_P(0, 0, _i("Connect printer to")); lcd_puts_at_P(0, 0, _i("Connect printer to"));
lcd_puts_at_P(0, 1, _i("monitoring or hold")); lcd_puts_at_P(0, 1, _i("monitoring or hold"));
lcd_puts_at_P(0, 2, _i("the knob to continue")); lcd_puts_at_P(0, 2, _i("the knob to continue"));
@ -8713,12 +8661,11 @@ static void lcd_connect_printer() {
i = 0; i = 0;
lcd_puts_at_P(0, 3, PSTR(" ")); lcd_puts_at_P(0, 3, PSTR(" "));
} }
if (i!=0) lcd_puts_at_P((i * 20) / (NC_BUTTON_LONG_PRESS * 10), 3, "\x01"); if (i!=0) lcd_puts_at_P((i * 20) / (NC_BUTTON_LONG_PRESS * 10), 3, "\xFF");
if (i == NC_BUTTON_LONG_PRESS * 10) { if (i == NC_BUTTON_LONG_PRESS * 10) {
no_response = false; no_response = false;
} }
} }
lcd_set_custom_characters_degree();
lcd_update_enable(true); lcd_update_enable(true);
lcd_update(2); lcd_update(2);
} }
@ -8726,7 +8673,7 @@ static void lcd_connect_printer() {
void lcd_ping() { //chceck if printer is connected to monitoring when in farm mode void lcd_ping() { //chceck if printer is connected to monitoring when in farm mode
if (farm_mode) { if (farm_mode) {
bool empty = is_buffer_empty(); bool empty = cmd_buffer_empty();
if ((_millis() - PingTime) * 0.001 > (empty ? PING_TIME : PING_TIME_LONG)) { //if commands buffer is empty use shorter time period if ((_millis() - PingTime) * 0.001 > (empty ? PING_TIME : PING_TIME_LONG)) { //if commands buffer is empty use shorter time period
//if there are comamnds in buffer, some long gcodes can delay execution of ping command //if there are comamnds in buffer, some long gcodes can delay execution of ping command
//therefore longer period is used //therefore longer period is used

View File

@ -155,6 +155,8 @@ extern uint8_t SilentModeMenu_MMU;
extern bool cancel_heatup; extern bool cancel_heatup;
extern bool isPrintPaused; extern bool isPrintPaused;
extern uint8_t scrollstuff;
void lcd_ignore_click(bool b=true); void lcd_ignore_click(bool b=true);
void lcd_commands(); void lcd_commands();
@ -228,10 +230,7 @@ void lcd_temp_calibration_set();
void display_loading(); void display_loading();
#if !SDSORT_USES_RAM
void lcd_set_degree(); void lcd_set_degree();
void lcd_set_progress();
#endif
#if (LANG_MODE != 0) #if (LANG_MODE != 0)
void lcd_language(); void lcd_language();

View File

@ -699,31 +699,29 @@ uint8_t xyzcal_find_pattern_12x12_in_32x32(uint8_t* pixels, uint16_t* pattern, u
const uint16_t xyzcal_point_pattern_10[12] PROGMEM = {0x000, 0x0f0, 0x1f8, 0x3fc, 0x7fe, 0x7fe, 0x7fe, 0x7fe, 0x3fc, 0x1f8, 0x0f0, 0x000}; const uint16_t xyzcal_point_pattern_10[12] PROGMEM = {0x000, 0x0f0, 0x1f8, 0x3fc, 0x7fe, 0x7fe, 0x7fe, 0x7fe, 0x3fc, 0x1f8, 0x0f0, 0x000};
const uint16_t xyzcal_point_pattern_08[12] PROGMEM = {0x000, 0x000, 0x0f0, 0x1f8, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x1f8, 0x0f0, 0x000, 0x000}; const uint16_t xyzcal_point_pattern_08[12] PROGMEM = {0x000, 0x000, 0x0f0, 0x1f8, 0x3fc, 0x3fc, 0x3fc, 0x3fc, 0x1f8, 0x0f0, 0x000, 0x000};
bool xyzcal_searchZ(void) bool xyzcal_searchZ(void) {
{ //@size=118
//@size=118
DBG(_n("xyzcal_searchZ x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]); DBG(_n("xyzcal_searchZ x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
int16_t x0 = _X; int16_t x0 = _X;
int16_t y0 = _Y; int16_t y0 = _Y;
int16_t z0 = _Z; int16_t z = _Z;
// int16_t min_z = -6000; // int16_t min_z = -6000;
// int16_t dz = 100; // int16_t dz = 100;
int16_t z = z0; while (z > -2300) { //-6mm + 0.25mm
while (z > -2300) //-6mm + 0.25mm
{
uint16_t ad = 0; uint16_t ad = 0;
if (xyzcal_spiral8(x0, y0, z, 100, 900, 320, 1, &ad)) //dz=100 radius=900 delay=400 if (xyzcal_spiral8(x0, y0, z, 100, 900, 320, 1, &ad)) { //dz=100 radius=900 delay=400
{
int16_t x_on = _X;
int16_t y_on = _Y;
int16_t z_on = _Z;
//@size=82 //@size=82
DBG(_n(" ON-SIGNAL at x=%d y=%d z=%d ad=%d\n"), x_on, y_on, z_on, ad); DBG(_n(" ON-SIGNAL at x=%d y=%d z=%d ad=%d\n"), _X, _Y, _Z, ad);
/// return to starting XY position
/// magic constant, lowers min_z after searchZ to obtain more dense data in scan
const pos_i16_t lower_z = 72;
xyzcal_lineXYZ_to(x0, y0, _Z - lower_z, 200, 0);
return true; return true;
} }
z -= 400; z -= 400;
} }
//@size=138 //@size=138
DBG(_n("xyzcal_searchZ no signal\n x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]); DBG(_n("xyzcal_searchZ no signal\n x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
return false; return false;
} }
@ -972,14 +970,10 @@ bool xyzcal_find_bed_induction_sensor_point_xy(void){
//@size=258 //@size=258
DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]); DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]);
st_synchronize(); st_synchronize();
///< magic constant, lowers min_z after searchZ to obtain more dense data in scan
const pos_i16_t lower_z = 72;
xyzcal_meassure_enter(); xyzcal_meassure_enter();
if (xyzcal_searchZ()){ if (xyzcal_searchZ())
xyzcal_lineXYZ_to(_X, _Y, _Z - lower_z, 200, 0);
ret = xyzcal_scan_and_process(); ret = xyzcal_scan_and_process();
}
xyzcal_meassure_leave(); xyzcal_meassure_leave();
return ret; return ret;
} }

View File

@ -139,6 +139,7 @@
# 12 Feb 2021, 3d-gussner, Add MK404-build.sh # 12 Feb 2021, 3d-gussner, Add MK404-build.sh
# 13 Feb 2021, 3d-gussner, Indentations # 13 Feb 2021, 3d-gussner, Indentations
# 13 Feb 2021, 3d-gussner, MK404 improvements like "flash" MK3, MK3S languages files to MK404 xflash. # 13 Feb 2021, 3d-gussner, MK404 improvements like "flash" MK3, MK3S languages files to MK404 xflash.
# 27 Feb 2021, 3d-gussner, Add './lang-community.sh' and update exits
#### Start check if OSTYPE is supported #### Start check if OSTYPE is supported
OS_FOUND=$( command -v uname) OS_FOUND=$( command -v uname)
@ -236,12 +237,12 @@ fi
# Check gawk ... needed during language build # Check gawk ... needed during language build
if ! type gawk > /dev/null; then if ! type gawk > /dev/null; then
if [ $TARGET_OS == "linux" ]; then if [ $TARGET_OS == "linux" ]; then
echo "$(tput setaf 1)Missing 'gawk' which is important to run this script" echo "$(tput setaf 1)Missing 'gawk' which is important to run this script"
echo "install it with the command $(tput setaf 2)'sudo apt-get install gawk'." echo "install it with the command $(tput setaf 2)'sudo apt-get install gawk'."
#sudo apt-get update && apt-get install gawk #sudo apt-get update && apt-get install gawk
exit 4 exit 5
fi fi
fi fi
#### End prepare bash / Linux environment #### End prepare bash / Linux environment
@ -281,10 +282,10 @@ echo ""
#Check if build exists and creates it if not #Check if build exists and creates it if not
if [ ! -d "../PF-build-dl" ]; then if [ ! -d "../PF-build-dl" ]; then
mkdir ../PF-build-dl || exit 5 mkdir ../PF-build-dl || exit 6
fi fi
cd ../PF-build-dl || exit 6 cd ../PF-build-dl || exit 7
BUILD_ENV_PATH="$( cd "$(dirname "$0")" ; pwd -P )" BUILD_ENV_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
# Check if PF-build-env-<version> exists and downloads + creates it if not # Check if PF-build-env-<version> exists and downloads + creates it if not
@ -298,20 +299,20 @@ fi
# Download and extract supported Arduino IDE depending on OS # Download and extract supported Arduino IDE depending on OS
# Windows # Windows
if [ $TARGET_OS == "windows" ]; then if [ $TARGET_OS == "windows" ]; then
if [ ! -f "arduino-$ARDUINO_ENV-windows.zip" ]; then if [ ! -f "arduino-$ARDUINO_ENV-windows.zip" ]; then
echo "$(tput setaf 6)Downloading Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)" echo "$(tput setaf 6)Downloading Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)"
sleep 2 sleep 2
wget https://downloads.arduino.cc/arduino-$ARDUINO_ENV-windows.zip || exit 7 wget https://downloads.arduino.cc/arduino-$ARDUINO_ENV-windows.zip || exit 8
echo "$(tput sgr 0)" echo "$(tput sgr 0)"
fi fi
if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" && ! -e "../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" && ! -e "../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then
echo "$(tput setaf 6)Unzipping Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)" echo "$(tput setaf 6)Unzipping Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)"
sleep 2 sleep 2
unzip arduino-$ARDUINO_ENV-windows.zip -d ../PF-build-env-$BUILD_ENV || exit 7 unzip arduino-$ARDUINO_ENV-windows.zip -d ../PF-build-env-$BUILD_ENV || exit 8
mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor
echo "# arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt echo "# arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
echo "$(tput sgr0)" echo "$(tput sgr0)"
fi fi
fi fi
# Linux # Linux
if [ $TARGET_OS == "linux" ]; then if [ $TARGET_OS == "linux" ]; then
@ -485,37 +486,36 @@ while getopts v:l:d:b:o:c:p:n:m:g:?h flag
# #
# '?' 'h' argument usage and help # '?' 'h' argument usage and help
if [ "$help_flag" == "1" ] ; then if [ "$help_flag" == "1" ] ; then
echo "***************************************" echo "***************************************"
echo "* PF-build.sh Version: 1.0.6-Build_33 *" echo "* PF-build.sh Version: 1.0.6-Build_33 *"
echo "***************************************" echo "***************************************"
echo "Arguments:" echo "Arguments:"
echo "$(tput setaf 2)-v$(tput sgr0) Variant '$(tput setaf 2)All$(tput sgr0)' or variant file name" echo "$(tput setaf 2)-v$(tput sgr0) Variant '$(tput setaf 2)All$(tput sgr0)' or variant file name"
echo "$(tput setaf 2)-l$(tput sgr0) Languages '$(tput setaf 2)ALL$(tput sgr0)' for multi language or '$(tput setaf 2)EN_ONLY$(tput sgr0)' for English only" echo "$(tput setaf 2)-l$(tput sgr0) Languages '$(tput setaf 2)ALL$(tput sgr0)' for multi language or '$(tput setaf 2)EN_ONLY$(tput sgr0)' for English only"
echo "$(tput setaf 2)-d$(tput sgr0) Devel build '$(tput setaf 2)GOLD$(tput sgr0)', '$(tput setaf 2)RC$(tput sgr0)', '$(tput setaf 2)BETA$(tput sgr0)', '$(tput setaf 2)ALPHA$(tput sgr0)', '$(tput setaf 2)DEBUG$(tput sgr0)', '$(tput setaf 2)DEVEL$(tput sgr0)' and '$(tput setaf 2)UNKNOWN$(tput sgr0)'" echo "$(tput setaf 2)-d$(tput sgr0) Devel build '$(tput setaf 2)GOLD$(tput sgr0)', '$(tput setaf 2)RC$(tput sgr0)', '$(tput setaf 2)BETA$(tput sgr0)', '$(tput setaf 2)ALPHA$(tput sgr0)', '$(tput setaf 2)DEBUG$(tput sgr0)', '$(tput setaf 2)DEVEL$(tput sgr0)' and '$(tput setaf 2)UNKNOWN$(tput sgr0)'"
echo "$(tput setaf 2)-b$(tput sgr0) Build/commit number '$(tput setaf 2)Auto$(tput sgr0)' needs git or a number" echo "$(tput setaf 2)-b$(tput sgr0) Build/commit number '$(tput setaf 2)Auto$(tput sgr0)' needs git or a number"
echo "$(tput setaf 2)-o$(tput sgr0) Output '$(tput setaf 2)1$(tput sgr0)' force or '$(tput setaf 2)0$(tput sgr0)' block output and delays" echo "$(tput setaf 2)-o$(tput sgr0) Output '$(tput setaf 2)1$(tput sgr0)' force or '$(tput setaf 2)0$(tput sgr0)' block output and delays"
echo "$(tput setaf 2)-c$(tput sgr0) Do not clean up lang build'$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" echo "$(tput setaf 2)-c$(tput sgr0) Do not clean up lang build'$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes"
echo "$(tput setaf 2)-p$(tput sgr0) Keep Configuration_prusa.h '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" echo "$(tput setaf 2)-p$(tput sgr0) Keep Configuration_prusa.h '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes"
echo "$(tput setaf 2)-n$(tput sgr0) New fresh build '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes" echo "$(tput setaf 2)-n$(tput sgr0) New fresh build '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes"
echo "$(tput setaf 2)-m$(tput sgr0) Start MK404 sim '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes '$(tput setaf 2)2$(tput sgr0)' with MMU2" echo "$(tput setaf 2)-m$(tput sgr0) Start MK404 sim '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' yes '$(tput setaf 2)2$(tput sgr0)' with MMU2"
echo "$(tput setaf 2)-g$(tput sgr0) Start MK404 grafics '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' lite '$(tput setaf 2)2$(tput sgr0)' fancy" echo "$(tput setaf 2)-g$(tput sgr0) Start MK404 grafics '$(tput setaf 2)0$(tput sgr0)' no '$(tput setaf 2)1$(tput sgr0)' lite '$(tput setaf 2)2$(tput sgr0)' fancy"
echo "$(tput setaf 2)-?$(tput sgr0) Help" echo "$(tput setaf 2)-?$(tput sgr0) Help"
echo "$(tput setaf 2)-h$(tput sgr0) Help" echo "$(tput setaf 2)-h$(tput sgr0) Help"
echo echo
echo "Brief USAGE:" echo "Brief USAGE:"
echo " $(tput setaf 2)./PF-build.sh$(tput sgr0) [-v] [-l] [-d] [-b] [-o] [-c] [-p] [-n] [-m]" echo " $(tput setaf 2)./PF-build.sh$(tput sgr0) [-v] [-l] [-d] [-b] [-o] [-c] [-p] [-n] [-m]"
echo echo
echo "Example:" echo "Example:"
echo " $(tput setaf 2)./PF-build.sh -v All -l ALL -d GOLD$(tput sgr0)" echo " $(tput setaf 2)./PF-build.sh -v All -l ALL -d GOLD$(tput sgr0)"
echo " Will build all variants as multi language and final GOLD version" echo " Will build all variants as multi language and final GOLD version"
echo echo
echo " $(tput setaf 2) ./PF-build.sh -v 1_75mm_MK3S-EINSy10a-E3Dv6full.h -b Auto -l ALL -d GOLD -o 1 -c 1 -p 1 -n 1$(tput sgr0)" echo " $(tput setaf 2) ./PF-build.sh -v 1_75mm_MK3S-EINSy10a-E3Dv6full.h -b Auto -l ALL -d GOLD -o 1 -c 1 -p 1 -n 1$(tput sgr0)"
echo " Will build MK3S multi language final GOLD firmware " echo " Will build MK3S multi language final GOLD firmware "
echo " with current commit count number and output extra information," echo " with current commit count number and output extra information,"
echo " not delete lang build temporary files, keep Configuration_prusa.h and build with new fresh build folder." echo " not delete lang build temporary files, keep Configuration_prusa.h and build with new fresh build folder."
echo echo
exit exit 14
fi fi
# #
@ -806,9 +806,9 @@ do
fi fi
#Check if compiler flags are set to Prusa specific needs for the rambo board. #Check if compiler flags are set to Prusa specific needs for the rambo board.
# if [ $TARGET_OS == "windows" ]; then #if [ $TARGET_OS == "windows" ]; then
# RAMBO_PLATFORM_FILE="PrusaResearchRambo/avr/platform.txt" #RAMBO_PLATFORM_FILE="PrusaResearchRambo/avr/platform.txt"
# fi #fi
#### End of Prepare building #### End of Prepare building
@ -873,6 +873,8 @@ do
# build languages # build languages
echo "$(tput setaf 3)" echo "$(tput setaf 3)"
./lang-build.sh || exit 32 ./lang-build.sh || exit 32
# build community languages
./lang-community.sh || exit 33
# Combine compiled firmware with languages # Combine compiled firmware with languages
./fw-build.sh || exit 33 ./fw-build.sh || exit 33
cp not_tran.txt not_tran_$VARIANT.txt cp not_tran.txt not_tran_$VARIANT.txt
@ -884,9 +886,9 @@ do
if [ "$MOTHERBOARD" = "BOARD_EINSY_1_0a" ]; then if [ "$MOTHERBOARD" = "BOARD_EINSY_1_0a" ]; then
echo "$(tput setaf 2)Copying multi language firmware for MK3/Einsy board to PF-build-hex folder$(tput sgr 0)" echo "$(tput setaf 2)Copying multi language firmware for MK3/Einsy board to PF-build-hex folder$(tput sgr 0)"
# Make a copy of "lang.bin" for MK404 MK3 and MK3S # Make a copy of "lang.bin" for MK404 MK3 and MK3S
if [ ! -z "$mk404_flag" ]; then #if [ ! -z "$mk404_flag" ]; then
cp -f lang.bin $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin #cp -f lang.bin $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin
fi #fi
# End of "lang.bin" for MK3 and MK3S copy # End of "lang.bin" for MK3 and MK3S copy
cp -f firmware.hex $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT.hex cp -f firmware.hex $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT.hex
else else
@ -975,43 +977,46 @@ echo "more information how to flash firmware https://www.prusa3d.com/drivers/ $(
# Check/compile MK404 sim # Check/compile MK404 sim
if [ ! -z "$mk404_flag" ]; then if [ ! -z "$mk404_flag" ]; then
./MK404-build.sh ./MK404-build.sh
# For Prusa MK2, MK2.5/S # For Prusa MK2, MK2.5/S
if [ "$MOTHERBOARD" == "BOARD_RAMBO_MINI_1_3" ]; then if [ "$MOTHERBOARD" == "BOARD_RAMBO_MINI_1_3" ]; then
PRINTER="${PRINTER}_mR13" PRINTER="${PRINTER}_mR13"
elif [ "$mk404_flag" == "2" ]; then # Check if MMU2 is selected only for MK3/S else
PRINTER="${PRINTER}MMU2" if [[ "$mk404_flag" == "2" || "$mk404_flag" == "MMU2" || "$mk404_flag" == "MMU2S" ]]; then # Check if MMU2 is selected only for MK3/S
fi PRINTER="${PRINTER}MMU2"
fi
fi
# Run MK404 with grafics # Run MK404 with grafics
if [ ! -z "$graphics_flag" ]; then if [ ! -z "$graphics_flag" ]; then
MK404_options="--colour-extrusion --extrusion Quad_HR -g " MK404_options="--colour-extrusion --extrusion Quad_HR -g "
if [ "$graphics_flag" == "1" ]; then if [[ "$graphics_flag" == "1" || "$graphics_flag" == "lite" ]]; then
MK404_options="${MK404_options}lite" MK404_options="${MK404_options}lite"
else elif [[ "$graphics_flag" == "2" || "$graphics_flag" == "fancy" ]]; then
MK404_options="${MK404_options}fancy" MK404_options="${MK404_options}fancy"
else
echo "$(tput setaf 1)Unsupported MK404 graphics option $graphics_flag$(tput sgr 0)"
fi
fi fi
fi
# Output some useful data # Output some useful data
echo "Printer: $PRINTER" echo "Printer: $PRINTER"
echo "Options: $MK404_options" echo "Options: $MK404_options"
# Change to MK404 build folder # Change to MK404 build folder
cd ../MK404/master/build cd ../MK404/master/build
# Copy language bin file for MK3 and MK3S to xflash # Copy language bin file for MK3 and MK3S to xflash
if [ -f $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin ]; then #if [ -f $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin ]; then
echo "Copy 'FW$FW-Build$BUILD-$VARIANT-lang.bin' to 'Prusa_${PRINTER}_xflash.bin'" #echo "Copy 'FW$FW-Build$BUILD-$VARIANT-lang.bin' to 'Prusa_${PRINTER}_xflash.bin'"
dd if=/dev/zero bs=1 count=262145 | tr "\000" "\377" >Prusa_${PRINTER}_xflash.bin #dd if=/dev/zero bs=1 count=262145 | tr "\000" "\377" >Prusa_${PRINTER}_xflash.bin
dd if=$SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin of=Prusa_${PRINTER}_xflash.bin conv=notrunc #dd if=$SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT-lang.bin of=Prusa_${PRINTER}_xflash.bin conv=notrunc
fi #fi
# Start MK404 # Start MK404
# default with serial output and terminal to manipulate it via terminal # default with serial output and terminal to manipulate it via terminal
./MK404 Prusa_$PRINTER -s --terminal $MK404_options -f $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT.hex ./MK404 Prusa_$PRINTER -s --terminal $MK404_options -f $SCRIPT_PATH/../$OUTPUT_FOLDER/FW$FW-Build$BUILD-$VARIANT.hex
fi fi
#### End of MK404 Simulator #### End of MK404 Simulator

View File

@ -38,4 +38,5 @@ export ARDUINO=$BUILD_ENV_PATH
cd $SCRIPT_PATH/lang cd $SCRIPT_PATH/lang
./lang-build.sh || exit 10 ./lang-build.sh || exit 10
./fw-build.sh || exit 11 ./lang-community.sh || exit 11
./fw-build.sh || exit 12

194
lang/Add_new_language.md Normal file
View File

@ -0,0 +1,194 @@
# How-to add a new language to Prusa Firmware
We will use Dutch as an example here.
## Prepare Prusa Firmware
QR = palceholder for language in upper case
qr = placehodler for language in lower case
AB = palceholder for hexadecial
Files needs to be modified
- `../Firmware/language.h`
In section `/** @name Language codes (ISO639-1)*/` add the new `#define LANG_CODE_QR 0xABAB //!<'qr'`following ISO639-1 convention for QR.
https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
Example:
`#define LANG_CODE_NL 0x6e6c //!<'nl'` where the hex value `0x6e6c` is in ascii `nl`
- `../Firmware/language.c`
In section `const char* lang_get_name_by_code(uint16_t code)` add `case LANG_CODE_NL: return _n("Language");`
Example:
`case LANG_CODE_NL: return _n("Nederlands");` Where `Language` is native spoken version, here `Nederlands` (Netherlands) or `Vlaams` (Belgium). This will be displayed on the LCD menu.
- `../lang/lang-add.sh`
In section `cat lang_add.txt | sed 's/^/"/;s/$/"/' | while read new_s; do` add `insert_qr "$new_s" 'qr'`where qr
Example:
`insert_qr "$new_s" 'nl'` with qr value `nl`for Dutch
- `../lang/lang-build.sh`
In section `#returns hexadecial data for lang code` add a case `*qr*) echo '0x71\0x72'`
Example:
`*nl*) echo '\x6c\x6e' ;;` !!! IMPORTANT that the hex values are switched so 'nl' is here in 'ln' !!!
In generate "all" section add `generate_binary 'qr'
Example:
`generate_binary 'nl'`
- `../lang/lang-check.py`
Add in `help` the new language `qr`
Example:
From `help="Check lang file (en|cs|de|es|fr|it|pl)")` to `help="Check lang file (en|cs|de|es|fr|nl|it|pl)")`
- In `../lang/lang-clean.sh`
In section echo `"lang-clean.sh started" >&2` add `clean_lang qr`
Example:
`clean_lang nl`
- `../lang/lang-export.sh`
In section `# if 'all' is selected, script will generate all po files and also pot file` add `./lang-export.sh qr`
Example:
`./lang-export.sh nl`
In section ` # language name in english` add `*qr*) echo "Language-in-English" ;;`
Example:
`*nl*) echo "Dutch" ;;`
- `../lang/lang-import.sh`
In section `#replace in languages translation` add new rule set for the language.
As the LCD screen doesn't not support äöüßéè and other special characters, it makes sense to "normalize" these.
Example:
```
#replace in dutch translation according to https://nl.wikipedia.org/wiki/Accenttekens_in_de_Nederlandse_spelling
if [ "$LNG" = "nl" ]; then
#replace 'ë' with 'e'
sed -i 's/\xc3\xab/e/g' $LNG'_filtered.po'
#replace 'ï' with 'i'
sed -i 's/\xc3\xaf/i/g' $LNG'_filtered.po'
#replace 'é' with 'e'
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
#replace 'è' with 'e' (left)
sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po'
#replace 'ö' with 'o' (left)
sed -i 's/\xc3\xb6/o/g' $LNG'_filtered.po'
#replace 'ê' with 'e' (left)
sed -i 's/\xc3\xaa/e/g' $LNG'_filtered.po'
#replace 'ü' with 'u' (left)
sed -i 's/\xc3\xbc/u/g' $LNG'_filtered.po'
#replace 'ç' with 'c' (left)
sed -i 's/\xc3\xa7/c/g' $LNG'_filtered.po'
#replace 'á' with 'a' (left)
sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po'
#replace 'à' with 'a' (left)
sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po'
#replace 'ä' with 'a' (left)
sed -i 's/\xc3\xa4/a/g' $LNG'_filtered.po'
#replace 'û' with 'u' (left)
sed -i 's/\xc3\xbc/u/g' $LNG'_filtered.po'
#replace 'î' with 'i' (left)
sed -i 's/\xc3\xae/i/g' $LNG'_filtered.po'
#replace 'í' with 'i' (left)
sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po'
#replace 'ô' with 'o' (left)
sed -i 's/\xc3\xb4/o/g' $LNG'_filtered.po'
#replace 'ú' with 'u' (left)
sed -i 's/\xc3\xba/u/g' $LNG'_filtered.po'
#replace 'ñ' with 'n' (left)
sed -i 's/\xc3\xb1/n/g' $LNG'_filtered.po'
#replace 'â' with 'a' (left)
sed -i 's/\xc3\xa2/a/g' $LNG'_filtered.po'
#replace 'Å' with 'A' (left)
sed -i 's/\xc3\x85/A/g' $LNG'_filtered.po'
fi
```
- `../lang/fw-build.sh`
In section `#update _SEC_LANG in binary file if language is selected` add
```
if [ -e lang_qr.bin ]; then
echo -n " Language-in-English : " >&2
./update_lang.sh qr 2>./update_lang_qr.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
```
Example:
```
if [ -e lang_nl.bin ]; then
echo -n " Dutch : " >&2
./update_lang.sh nl 2>./update_lang_nl.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
```
In section `#create binary file with all languages` add `if [ -e lang_qr.bin ]; then cat lang_qr.bin >> lang.bin; fi`
Example:
`if [ -e lang_nl.bin ]; then cat lang_nl.bin >> lang.bin; fi`
- `../lang/fw-clean.sh`
In section `echo "fw-clean.sh started" >&2` add
```
rm_if_exists firmware_qr.hex
...
...
rm_if_exists update_lang_qr.out
```
Example:
`rm_if_exists firmware_nl.hex`
and
`rm_if_exists update_lang_nl.out`
## Prepare language part
To prepare the acutal language translation files we need create the `lang_en_qr.txt` file.
1. Copy and `lang_en.txt` as `lang_en_qr.txt`
2. run `../lang/lang-export.sh`
3. copy `../lang/po/Firmware_qr.po` file to `../lang/po/new/qr.po`
4. translate all messages using POEdit or other tools.
5. use `lang/lang-import.sh qr` to generate `lang_en_qr.txt` from translated po files
6. move `../lang/po/new/lang_en_qr.txt` to `../lang/lang_en_qr.txt`
7. cleanup `../lang/po/new` folder by deleting
```
qr_filtered.po
qr_new.po
noasci.txt
```
##

View File

@ -163,6 +163,22 @@ else
./update_lang.sh pl 2>./update_lang_pl.out 1>/dev/null ./update_lang.sh pl 2>./update_lang_pl.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; finish 1; fi if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; finish 1; fi
fi fi
#Community language support
#Dutch
if [ -e lang_nl.bin ]; then
echo -n " Dutch : " >&2
./update_lang.sh nl 2>./update_lang_nl.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
#Use the 6 lines below as a template and replace 'qr' and 'New language'
#New language
# if [ -e lang_qr.bin ]; then
# echo -n " New language : " >&2
# ./update_lang.sh qr 2>./update_lang_qr.out 1>/dev/null
# if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
# fi
# echo "skipped" >&2 # echo "skipped" >&2
fi fi
@ -174,6 +190,13 @@ if [ -e lang_es.bin ]; then cat lang_es.bin >> lang.bin; fi
if [ -e lang_fr.bin ]; then cat lang_fr.bin >> lang.bin; fi if [ -e lang_fr.bin ]; then cat lang_fr.bin >> lang.bin; fi
if [ -e lang_it.bin ]; then cat lang_it.bin >> lang.bin; fi if [ -e lang_it.bin ]; then cat lang_it.bin >> lang.bin; fi
if [ -e lang_pl.bin ]; then cat lang_pl.bin >> lang.bin; fi if [ -e lang_pl.bin ]; then cat lang_pl.bin >> lang.bin; fi
#Community language support
# Dutch
if [ -e lang_nl.bin ]; then cat lang_nl.bin >> lang.bin; fi
#Use the 2 lines below as a template and replace 'qr'
## New language
#if [ -e lang_qr.bin ]; then cat lang_qr.bin >> lang.bin; fi
#convert lang.bin to lang.hex #convert lang.bin to lang.hex
echo -n " converting to hex..." >&2 echo -n " converting to hex..." >&2

View File

@ -45,9 +45,17 @@ rm_if_exists update_lang_de.out
rm_if_exists update_lang_es.out rm_if_exists update_lang_es.out
rm_if_exists update_lang_fr.out rm_if_exists update_lang_fr.out
rm_if_exists update_lang_it.out rm_if_exists update_lang_it.out
rm_if_exists update_lang_nl.out
rm_if_exists update_lang_pl.out rm_if_exists update_lang_pl.out
rm_if_exists lang.bin rm_if_exists lang.bin
rm_if_exists lang.hex rm_if_exists lang.hex
#Community language support
#Dutch
rm_if_exists firmware_nl.hex
#Use the 2 lines below as a template and replace 'qr'
##New language
#rm_if_exists firmware_qr.hex
echo -n "fw-clean.sh finished" >&2 echo -n "fw-clean.sh finished" >&2
if [ $result -eq 0 ]; then if [ $result -eq 0 ]; then

View File

@ -66,6 +66,13 @@ cat lang_add.txt | sed 's/^/"/;s/$/"/' | while read new_s; do
insert_xx "$new_s" 'fr' insert_xx "$new_s" 'fr'
insert_xx "$new_s" 'it' insert_xx "$new_s" 'it'
insert_xx "$new_s" 'pl' insert_xx "$new_s" 'pl'
#Community language support
#Dutch
insert_xx "$new_s" 'nl'
#Use the 2 lines below as a template and replace 'qr'
##New language
# insert_xx "$new_s" 'qr'
fi fi
done done

View File

@ -43,6 +43,12 @@ lang_code_hex_data()
*fr*) echo '\x72\x66' ;; *fr*) echo '\x72\x66' ;;
*it*) echo '\x74\x69' ;; *it*) echo '\x74\x69' ;;
*pl*) echo '\x6c\x70' ;; *pl*) echo '\x6c\x70' ;;
#Community language support
#Dutch
*nl*) echo '\x6c\x6e' ;;
#Use the 2 lines below as a template and replace 'qr' and `\x71\x72`
##New language
# *qr*) echo '\x71\x72' ;;
esac esac
echo '??' echo '??'
} }
@ -135,6 +141,7 @@ if [ "$1" = "all" ]; then
generate_binary 'fr' generate_binary 'fr'
generate_binary 'it' generate_binary 'it'
generate_binary 'pl' generate_binary 'pl'
#DO NOT add Community languages here !!!
else else
generate_binary $1 generate_binary $1
fi fi

View File

@ -56,7 +56,7 @@ def main():
usage="$(prog)s lang") usage="$(prog)s lang")
parser.add_argument( parser.add_argument(
"lang", nargs='?', default="en", type=str, "lang", nargs='?', default="en", type=str,
help="Check lang file (en|cs|de|es|fr|it|pl)") help="Check lang file (en|cs|de|es|fr|nl|it|pl)")
parser.add_argument( parser.add_argument(
"--no-warning", action="store_true", "--no-warning", action="store_true",
help="Disable warnings") help="Disable warnings")

View File

@ -46,6 +46,13 @@ clean_lang es
clean_lang fr clean_lang fr
clean_lang it clean_lang it
clean_lang pl clean_lang pl
#Community language support
#Dutch
clean_lang nl
#Use the 2 lines below as a template and replace 'qr'
##New language
#clean_lang_qr
echo -n "lang-clean.sh finished" >&2 echo -n "lang-clean.sh finished" >&2
if [ $result -eq 0 ]; then if [ $result -eq 0 ]; then

53
lang/lang-community.sh Executable file
View File

@ -0,0 +1,53 @@
#!/bin/sh
#
# lang-community.sh - Community language support script
# Check community languages are defined in `config.h`
#
# Root path
if [ -z "$ROOT_PATH" ]; then
export ROOT_PATH=".."
fi
# Check community language NL = Dutch
COMMUNITY_LANG_NL=$(grep --max-count=1 "^#define COMMUNITY_LANG_NL" $ROOT_PATH/Firmware/config.h| cut -d '_' -f3 |cut -d ' ' -f1)
export NL=$COMMUNITY_LANG_NL
# Use the lines below as a template and replace 'QR' and 'new language'
# Check comminity language QR = new language
#COMMUNITY_LANG_QR=$(grep --max-count=1 "^#define COMMUNITY_LANG_QR" $ROOT_PATH/Firmware/config.h| cut -d '_' -f3 |cut -d ' ' -f1)
#export QR=$COMMUNITY_LANG_QR
#startup message
echo "lang-community.sh started" >&2
echo -n " Source code path: " >&2
if [ -e $ROOT_PATH ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=1; fi
echo " Found: " >&2
if [ "$COMMUNITY_LANG_NL" = "NL" ]; then
echo " $COMMUNITY_LANG_NL" >&2
echo
./lang-build.sh nl
fi
# Use the 5 lines below as a template and replace 'QR' and 'qr'
#if [ "$COMMUNITY_LANG_QR" = "QR" ]; then
# echo " $COMMUNITY_LANG_QR" >&2
# echo
# ./lang-build.sh qr
#fi
#exiting function
finish()
{
if [ $1 -eq 0 ]; then
echo "lang-community.sh finished with success" >&2
else
echo "lang-community.sh finished with errors!" >&2
fi
echo
exit $1
}
finish 0

View File

@ -22,6 +22,12 @@ if [ "$LNG" = "all" ]; then
./lang-export.sh fr ./lang-export.sh fr
./lang-export.sh it ./lang-export.sh it
./lang-export.sh pl ./lang-export.sh pl
#Community language support
#Dutch
./lang-export.sh nl
#Use the 2 lines below as a template and replace 'qr' and 'New language'
##New language
# ./lang-export.sh qr
exit 0 exit 0
fi fi
@ -48,6 +54,12 @@ else
*fr*) echo "French" ;; *fr*) echo "French" ;;
*it*) echo "Italian" ;; *it*) echo "Italian" ;;
*pl*) echo "Polish" ;; *pl*) echo "Polish" ;;
#Community language support
#Dutch
*nl*) echo "Dutch" ;;
#Use the 2 lines below as a template and replace 'qr' and 'New language'
##New language
# *qr*) echo "New language" ;;
esac) esac)
# unknown language - error # unknown language - error
if [ -z "LNGNAME" ]; then if [ -z "LNGNAME" ]; then

View File

@ -15,6 +15,7 @@ if [ "$LNG" = "all" ]; then
./lang-import.sh fr ./lang-import.sh fr
./lang-import.sh it ./lang-import.sh it
./lang-import.sh pl ./lang-import.sh pl
#DO NOT add Community languages here !!!
exit 0 exit 0
fi fi
@ -40,51 +41,51 @@ sed -i 's/ \\n/ /g;s/\\n/ /g' $LNG'_filtered.po'
#replace in czech translation #replace in czech translation
if [ "$LNG" = "cz" ]; then if [ "$LNG" = "cz" ]; then
#replace 'ž' with 'z' #replace 'ž' with 'z'
sed -i 's/\xc5\xbe/z/g' $LNG'_filtered.po' sed -i 's/\xc5\xbe/z/g' $LNG'_filtered.po'
#replace 'ì' with 'e' #replace 'ì' with 'e'
sed -i 's/\xc4\x9b/e/g' $LNG'_filtered.po' sed -i 's/\xc4\x9b/e/g' $LNG'_filtered.po'
#replace 'í' with 'i' #replace 'í' with 'i'
sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po' sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po'
#replace 'ø' with 'r' #replace 'ø' with 'r'
sed -i 's/\xc5\x99/r/g' $LNG'_filtered.po' sed -i 's/\xc5\x99/r/g' $LNG'_filtered.po'
#replace 'è' with 'c' #replace 'è' with 'c'
sed -i 's/\xc4\x8d/c/g' $LNG'_filtered.po' sed -i 's/\xc4\x8d/c/g' $LNG'_filtered.po'
#replace 'á' with 'a' #replace 'á' with 'a'
sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po' sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po'
#replace 'é' with 'e' #replace 'é' with 'e'
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
fi fi
#replace in german translation https://en.wikipedia.org/wiki/German_orthography #replace in german translation https://en.wikipedia.org/wiki/German_orthography
if [ "$LNG" = "de" ]; then if [ "$LNG" = "de" ]; then
#replace 'ä' with 'ae' #replace 'ä' with 'ae'
sed -i 's/\xc3\xa4/ae/g' $LNG'_filtered.po' sed -i 's/\xc3\xa4/ae/g' $LNG'_filtered.po'
#replace 'Ä' with 'Ae' #replace 'Ä' with 'Ae'
sed -i 's/\xc3\x84/Ae/g' $LNG'_filtered.po' sed -i 's/\xc3\x84/Ae/g' $LNG'_filtered.po'
#replace 'ü' with 'ue' #replace 'ü' with 'ue'
sed -i 's/\xc3\xbc/ue/g' $LNG'_filtered.po' sed -i 's/\xc3\xbc/ue/g' $LNG'_filtered.po'
#replace 'Ü' with 'Ue' #replace 'Ü' with 'Ue'
sed -i 's/\xc3\x9c/Ue/g' $LNG'_filtered.po' sed -i 's/\xc3\x9c/Ue/g' $LNG'_filtered.po'
#replace 'ö' with 'oe' #replace 'ö' with 'oe'
sed -i 's/\xc3\xb6/oe/g' $LNG'_filtered.po' sed -i 's/\xc3\xb6/oe/g' $LNG'_filtered.po'
#replace 'Ö' with 'Oe' #replace 'Ö' with 'Oe'
sed -i 's/\xc3\x96/Oe/g' $LNG'_filtered.po' sed -i 's/\xc3\x96/Oe/g' $LNG'_filtered.po'
#replace 'ß' with 'ss' #replace 'ß' with 'ss'
sed -i 's/\xc3\x9f/ss/g' $LNG'_filtered.po' sed -i 's/\xc3\x9f/ss/g' $LNG'_filtered.po'
fi fi
#replace in spain translation #replace in spain translation
if [ "$LNG" = "es" ]; then if [ "$LNG" = "es" ]; then
#replace 'á' with 'a' #replace 'á' with 'a'
sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po' sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po'
#replace '¿' with '?' #replace '¿' with '?'
sed -i 's/\xc2\xbf/?/g' $LNG'_filtered.po' sed -i 's/\xc2\xbf/?/g' $LNG'_filtered.po'
#replace 'ó' with 'o' #replace 'ó' with 'o'
sed -i 's/\xc3\xb3/o/g' $LNG'_filtered.po' sed -i 's/\xc3\xb3/o/g' $LNG'_filtered.po'
#replace 'é' with 'e' #replace 'é' with 'e'
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
#replace 'í' with 'i' #replace 'í' with 'i'
sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po' sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po'
#replace '!' with '!' #replace '!' with '!'
sed -i 's/\xc2\xa1/!/g' $LNG'_filtered.po' sed -i 's/\xc2\xa1/!/g' $LNG'_filtered.po'
@ -94,40 +95,82 @@ fi
#replace in french translation https://en.wikipedia.org/wiki/French_orthography #replace in french translation https://en.wikipedia.org/wiki/French_orthography
if [ "$LNG" = "fr" ]; then if [ "$LNG" = "fr" ]; then
#replace 'á' with 'a' (right) #replace 'á' with 'a' (right)
sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po' sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po'
#replace 'Á' with 'A' (right) #replace 'Á' with 'A' (right)
sed -i 's/\xc3\x81/A/g' $LNG'_filtered.po' sed -i 's/\xc3\x81/A/g' $LNG'_filtered.po'
#replace 'à' with 'a' (left) #replace 'à' with 'a' (left)
sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po' sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po'
#replace 'À' with 'A' (left) #replace 'À' with 'A' (left)
sed -i 's/\xc3\x80/A/g' $LNG'_filtered.po' sed -i 's/\xc3\x80/A/g' $LNG'_filtered.po'
#replace 'é' with 'e' (right) #replace 'é' with 'e' (right)
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
#replace 'É' with 'E' (right) #replace 'É' with 'E' (right)
sed -i 's/\xc3\x89/E/g' $LNG'_filtered.po' sed -i 's/\xc3\x89/E/g' $LNG'_filtered.po'
#replace 'è' with 'e' (left) #replace 'è' with 'e' (left)
sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po'
#replace 'È' with 'E' (left) #replace 'È' with 'E' (left)
sed -i 's/\xc3\x88/E/g' $LNG'_filtered.po' sed -i 's/\xc3\x88/E/g' $LNG'_filtered.po'
fi fi
#replace in italian translation #replace in italian translation
if [ "$LNG" = "it" ]; then if [ "$LNG" = "it" ]; then
#replace 'é' with 'e' (left) #replace 'é' with 'e' (left)
sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po'
#replace 'á' with 'a' (left) #replace 'á' with 'a' (left)
sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po' sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po'
#replace 'ó' with 'o' (left) #replace 'ó' with 'o' (left)
sed -i 's/\xc3\xb2/o/g' $LNG'_filtered.po' sed -i 's/\xc3\xb2/o/g' $LNG'_filtered.po'
#replace 'ú' with 'u' (left) #replace 'ú' with 'u' (left)
sed -i 's/\xc3\xb9/u/g' $LNG'_filtered.po' sed -i 's/\xc3\xb9/u/g' $LNG'_filtered.po'
#replace 'é' with 'e' #replace 'é' with 'e'
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po' sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
#replace 'É' with 'E' (left) #replace 'É' with 'E' (left)
sed -i 's/\xc3\x88/E/g' $LNG'_filtered.po' sed -i 's/\xc3\x88/E/g' $LNG'_filtered.po'
fi fi
#replace in dutch translation according to https://nl.wikipedia.org/wiki/Accenttekens_in_de_Nederlandse_spelling
if [ "$LNG" = "nl" ]; then
#replace 'ë' with 'e'
sed -i 's/\xc3\xab/e/g' $LNG'_filtered.po'
#replace 'ï' with 'i'
sed -i 's/\xc3\xaf/i/g' $LNG'_filtered.po'
#replace 'é' with 'e'
sed -i 's/\xc3\xa9/e/g' $LNG'_filtered.po'
#replace 'è' with 'e' (left)
sed -i 's/\xc3\xa8/e/g' $LNG'_filtered.po'
#replace 'ö' with 'o' (left)
sed -i 's/\xc3\xb6/o/g' $LNG'_filtered.po'
#replace 'ê' with 'e' (left)
sed -i 's/\xc3\xaa/e/g' $LNG'_filtered.po'
#replace 'ü' with 'u' (left)
sed -i 's/\xc3\xbc/u/g' $LNG'_filtered.po'
#replace 'ç' with 'c' (left)
sed -i 's/\xc3\xa7/c/g' $LNG'_filtered.po'
#replace 'á' with 'a' (left)
sed -i 's/\xc3\xa1/a/g' $LNG'_filtered.po'
#replace 'à' with 'a' (left)
sed -i 's/\xc3\xa0/a/g' $LNG'_filtered.po'
#replace 'ä' with 'a' (left)
sed -i 's/\xc3\xa4/a/g' $LNG'_filtered.po'
#replace 'û' with 'u' (left)
sed -i 's/\xc3\xbc/u/g' $LNG'_filtered.po'
#replace 'î' with 'i' (left)
sed -i 's/\xc3\xae/i/g' $LNG'_filtered.po'
#replace 'í' with 'i' (left)
sed -i 's/\xc3\xad/i/g' $LNG'_filtered.po'
#replace 'ô' with 'o' (left)
sed -i 's/\xc3\xb4/o/g' $LNG'_filtered.po'
#replace 'ú' with 'u' (left)
sed -i 's/\xc3\xba/u/g' $LNG'_filtered.po'
#replace 'ñ' with 'n' (left)
sed -i 's/\xc3\xb1/n/g' $LNG'_filtered.po'
#replace 'â' with 'a' (left)
sed -i 's/\xc3\xa2/a/g' $LNG'_filtered.po'
#replace 'Å' with 'A' (left)
sed -i 's/\xc3\x85/A/g' $LNG'_filtered.po'
fi
#replace in polish translation #replace in polish translation
#if [ "$LNG" = "pl" ]; then #if [ "$LNG" = "pl" ]; then
#fi #fi

View File

@ -175,6 +175,9 @@
#MSG_DATE c=17 r=1 #MSG_DATE c=17 r=1
"Date:" "Date:"
#MSG_COMMUNITY_MADE c=18
"Community made"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Datum:" "Datum:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Vypnout motory" "Vypnout motory"

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Datum:" "Datum:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Motoren aus" "Motoren aus"

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Fecha:" "Fecha:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Apagar motores" "Apagar motores"

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Date:" "Date:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Desactiver moteurs" "Desactiver moteurs"

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Data:" "Data:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Disabilita motori" "Disabilita motori"

1480
lang/lang_en_nl.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -234,6 +234,10 @@
"Date:" "Date:"
"Data:" "Data:"
#MSG_COMMUNITY_MADE c=18
"Community made"
"\x00"
#MSG_DISABLE_STEPPERS #MSG_DISABLE_STEPPERS
"Disable steppers" "Disable steppers"
"Wylacz silniki" "Wylacz silniki"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1867
lang/po/Firmware_nl.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1842
lang/po/new/nl.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,22 +4,22 @@
- Build firmware - Build firmware
- using `build.sh` - using `build.sh`
- using `PF-build.sh` with a `break` before `# build languages` - using `PF-build.sh` with a parameter `-c 1` to keep lang build files after compiling
- change to `lang` folder - change to `lang` folder
- check if lang scripts being able to run with `config.sh` - check if lang scripts being able to run with `config.sh`
- if you get `Arduino main folder: NG` message change in `config.sh` `export ARDUINO=C:/arduino-1.8.5` to `export ARDUINO=<Path to your Arduino IDE folder>` - if you get `Arduino main folder: NG` message change in `config.sh` `export ARDUINO=C:/arduino-1.8.5` to `export ARDUINO=<Path to your Arduino IDE folder>`
-example: `export ARDUINO=D:/Github/Prusa-Firmware/PF-build-env-1.0.6/windows-64` -example: `export ARDUINO=D:/Github/Prusa-Firmware/PF-build-env-1.0.6/windows-64`
- run `lang-build.sh en` to create english `lang_en.tmp`, `lang_en.dat` and `lang_en.bin` files - run `lang-build.sh en` to create english `lang_en.tmp`, `lang_en.dat` and `lang_en.bin` files
- change in `fw-build.sh` `IGNORE_MISSING_TEXT=1` to `IGNORE_MISSING_TEXT=0` so it stops with error and generates `not_used.txt` and `not_tran.txt` - change in `fw-build.sh` `IGNORE_MISSING_TEXT=1` to `IGNORE_MISSING_TEXT=0` so it stops with error and generates `not_used<variant>.txt` and `not_tran<variant>.txt`
- run modified `fw-build.sh` - run modified `fw-build.sh`
- `not_tran.txt` should be reviewed and added as these are potential missing translations - `not_tran<variant>.txt` should be reviewed and added as these are potential missing translations
- copy `not_tran.txt` as `lang_add.txt` - copy `not_tran<variant>.txt` as `lang_add.txt`
- check if there are things you don't want to translate or must be modifed - check if there are things you don't want to translate or must be modifed
- als check that the strings do not start with `spaces` as the scripts doesn't handle these well at this moment. - als check that the strings do not start with `spaces` as the scripts doesn't handle these well at this moment.
- run `lang-add.sh lang_add.txt` to add the missing translations to `lang_en.txt` and `lang_en_??.txt` - run `lang-add.sh lang_add.txt` to add the missing translations to `lang_en.txt` and `lang_en_??.txt`
- `not_used.txt` should only contain mesages that aren't used in this variant like MK2.5 vs MK3 - `not_used<variant>.txt` should only contain messages that aren't used in this variant like MK2.5/S vs MK3/S
- run `fw-clean.sh` to cleanup firmware related files - run `fw-clean.sh` to cleanup firmware related files
- delete `not_used.txt` and `not_tran.txt` - delete `not_used<variant>.txt` and `not_tran<variant>.txt`
- run `lang-clean.sh` to cleanup language related files - run `lang-clean.sh` to cleanup language related files
- run `lang-export.sh all` to create PO files for translation these are stored in `/lang/po` folder - run `lang-export.sh all` to create PO files for translation these are stored in `/lang/po` folder
- Send them to translators and reviewers or - Send them to translators and reviewers or
@ -30,13 +30,12 @@
- run `lang-import.sh <language code (iso639-1)>` for each newly translated language - run `lang-import.sh <language code (iso639-1)>` for each newly translated language
- script improvement to import "all" and other things would be great. - script improvement to import "all" and other things would be great.
- Double check if something is missing or faulty - Double check if something is missing or faulty
- run `lang-build.sh` to to create `lang_en.tmp/.dat/.bin` and `lang_en_??.tmp/.dat/.bin` files - run `PF-build.sh -v all -n 1 -c 1` to compile for all variants files
- run `fw-build.sh` and check if there are still some messages in `not_tran.txt` that need attention - check if there are still some messages in `not_tran<variant>.txt` that need attention
- After approval - After approval
- run `fw-clean.sh` to cleanup firmware related files - run `fw-clean.sh` to cleanup firmware related files
- run `lang-clean.sh` to cleanup language related files - run `lang-clean.sh` to cleanup language related files
- change in `fw-build.sh` back to `IGNORE_MISSING_TEXT=1` - change in `fw-build.sh` back to `IGNORE_MISSING_TEXT=1`
- remove `break` from `PF-build.sh` script if that has been modified
- build your firmware with `build.sh`, `PF-build.sh` or how you normally do it. - build your firmware with `build.sh`, `PF-build.sh` or how you normally do it.
- Check/Test firmware on printer - Check/Test firmware on printer