diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 00f9f28b..d9240234 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -99,6 +99,7 @@ #ifdef W25X20CL #include "w25x20cl.h" +#include "optiboot_w25x20cl.h" #endif //W25X20CL #ifdef BLINKM @@ -194,6 +195,7 @@ // M84 - Disable steppers until next move, // or use S to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. // M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) +// M86 - Set safety timer expiration time with parameter S; M86 S0 will disable safety timer // M92 - Set axis_steps_per_unit - same syntax as G92 // M104 - Set extruder target temp // M105 - Read current temp @@ -492,6 +494,7 @@ const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42 static unsigned long previous_millis_cmd = 0; unsigned long max_inactive_time = 0; static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l; +static unsigned long safetytimer_inactive_time = DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul; unsigned long starttime=0; unsigned long stoptime=0; @@ -1111,7 +1114,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes) printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count); printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum); printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff); - printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1); + printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature); addr += header.size; codes[count] = header.code; @@ -1139,6 +1142,10 @@ void list_sec_lang_from_external_flash() // are initialized by the main() routine provided by the Arduino framework. void setup() { +#ifdef W25X20CL + // Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. + optiboot_w25x20cl_enter(); +#endif lcd_init(); fdev_setup_stream(lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); //setup lcdout stream @@ -1184,7 +1191,7 @@ void setup() #ifdef DEBUG_SEC_LANG lang_table_header_t header; uint32_t src_addr = 0x00000; - if (lang_get_header(3, &header, &src_addr)) + if (lang_get_header(1, &header, &src_addr)) { //this is comparsion of some printing-methods regarding to flash space usage and code size/readability #define LT_PRINT_TEST 2 @@ -1201,7 +1208,7 @@ void setup() printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count); printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum); printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff); - printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1); + printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature); #elif (LT_PRINT_TEST==2) //optimized printf printf_P( _n( @@ -1219,7 +1226,7 @@ void setup() header.count, header.count, header.checksum, header.code, header.code >> 8, header.code & 0xff, - header.reserved1 + header.signature ); #elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved) MYSERIAL.print(" _src_addr = 0x"); @@ -1246,7 +1253,7 @@ void setup() MYSERIAL.print((char)(header.code & 0xff), 0); MYSERIAL.println(")"); MYSERIAL.print(" _lt_resv1 = 0x"); - MYSERIAL.println(header.reserved1, 16); + MYSERIAL.println(header.signature, 16); #endif //(LT_PRINT_TEST==) #undef LT_PRINT_TEST @@ -1259,7 +1266,22 @@ void setup() if ((i % 16) == 15) putchar('\n'); } #endif -#if 1 + uint16_t sum = 0; + for (uint16_t i = 0; i < header.size; i++) + sum += (uint16_t)pgm_read_byte((uint8_t*)(_SEC_LANG_TABLE + i)) << ((i & 1)?0:8); + printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum); + sum -= header.checksum; //subtract checksum + printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum); + sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes + if (sum == header.checksum) + printf_P(_n("Checksum OK\n"), sum); + else + printf_P(_n("Checksum NG\n"), sum); + } + else + printf_P(_n("lang_get_header failed!\n")); + +#if 0 for (uint16_t i = 0; i < 1024*10; i++) { if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i); @@ -1267,10 +1289,6 @@ void setup() if ((i % 16) == 15) putchar('\n'); } #endif - } - else - printf_P(_n("lang_get_header failed!\n")); - #if 0 SERIAL_ECHOLN("Reading eeprom from 0 to 100: start"); @@ -5435,6 +5453,15 @@ Sigma_Exit: max_inactive_time = code_value() * 1000; } break; +#ifdef SAFETYTIMER + case 86: // M86 - set safety timer expiration time in seconds; M86 S0 will disable safety timer + //when safety timer expires heatbed and nozzle target temperatures are set to zero + if (code_seen('S')) { + safetytimer_inactive_time = code_value() * 1000; + safetyTimer.start(); + } + break; +#endif case 92: // M92 for(int8_t i=0; i < NUM_AXIS; i++) { @@ -7418,18 +7445,20 @@ void handle_status_leds(void) { #ifdef SAFETYTIMER /** - * @brief Turn off heating after 30 minutes of inactivity + * @brief Turn off heating after safetytimer_inactive_time milliseconds of inactivity * * Full screen blocking notification message is shown after heater turning off. * Paused print is not considered inactivity, as nozzle is cooled anyway and bed cooling would * damage print. + * + * If safetytimer_inactive_time is zero, feature is disabled (heating is never turned off because of inactivity) */ static void handleSafetyTimer() { #if (EXTRUDERS > 1) #error Implemented only for one extruder. #endif //(EXTRUDERS > 1) - if ((PRINTER_ACTIVE) || (!degTargetBed() && !degTargetHotend(0))) + if ((PRINTER_ACTIVE) || (!degTargetBed() && !degTargetHotend(0)) || (!safetytimer_inactive_time)) { safetyTimer.stop(); } @@ -7437,7 +7466,7 @@ static void handleSafetyTimer() { safetyTimer.start(); } - else if (safetyTimer.expired(1800000ul)) //30 min + else if (safetyTimer.expired(safetytimer_inactive_time)) { setTargetBed(0); setTargetHotend(0, 0); diff --git a/Firmware/config.h b/Firmware/config.h index a9172429..85687a4b 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -29,7 +29,7 @@ //LANG - Multi-language support //#define LANG_MODE 0 // primary language only #define LANG_MODE 1 // sec. language support -#define LANG_SIZE_RESERVED 0x2700 // reserved space for secondary language (~10kb) +#define LANG_SIZE_RESERVED 0x2400 // reserved space for secondary language (~10kb) //#define LANG_SIZE_RESERVED 0x1ef8 // reserved space for secondary language (~10kb) diff --git a/Firmware/language.c b/Firmware/language.c index acac7d1b..b79da8ff 100644 --- a/Firmware/language.c +++ b/Firmware/language.c @@ -28,6 +28,9 @@ uint8_t lang_is_selected(void) { return 1; } //reserved xx kbytes for secondary language table const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG"; +//primary language signature +const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff}; + //lang_table pointer lang_table_t* lang_table = 0; @@ -56,8 +59,12 @@ uint8_t lang_select(uint8_t lang) { if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid { - lang_table = _SEC_LANG_TABLE; // set table pointer - lang_selected = lang; // set language id + if (lang_check(_SEC_LANG_TABLE)) + if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid + { + lang_table = _SEC_LANG_TABLE; // set table pointer + lang_selected = lang; // set language id + } } } #else //W25X20CL @@ -70,6 +77,18 @@ uint8_t lang_select(uint8_t lang) return 0; } +uint8_t lang_check(uint16_t addr) +{ + uint16_t sum = 0; + uint16_t size = pgm_read_word((uint16_t*)(addr + 4)); + uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8)); + uint16_t i; for (i = 0; i < size; i++) + sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8); + sum -= lt_sum; //subtract checksum + sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes + return (sum == lt_sum); +} + uint8_t lang_get_count() { #ifdef W25X20CL @@ -98,7 +117,7 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off uint16_t ui = _SEC_LANG_TABLE; //table pointer memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem if (offset) *offset = ui; - return (header == LANG_MAGIC)?1:0; //return 1 if magic valid + return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid } W25X20CL_SPI_ENTER(); uint32_t addr = 0x00000; //start of xflash diff --git a/Firmware/language.h b/Firmware/language.h index 359bc083..509b0bc6 100644 --- a/Firmware/language.h +++ b/Firmware/language.h @@ -52,7 +52,7 @@ typedef struct uint16_t count; //+6 uint16_t checksum; //+8 uint16_t code; //+10 - uint32_t reserved1; //+12 + uint32_t signature; //+12 } lang_table_header_t; //lang_table_t structure - (size= 16byte + 2*count) @@ -98,10 +98,13 @@ extern uint8_t lang_selected; extern const char _SEC_LANG[LANG_SIZE_RESERVED]; extern const char* lang_get_translation(const char* s); #define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00) +//extern const uint32_t _PRI_LANG_SIGNATURE; #endif //(LANG_MODE != 0) //selects language, eeprom is updated in case of success extern uint8_t lang_select(uint8_t lang); +//performs checksum test of secondary language data +extern uint8_t lang_check(uint16_t addr); //returns total number of languages (primary + all in xflash) extern uint8_t lang_get_count(void); //reads lang table header and offset in xflash or progmem diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp new file mode 100644 index 00000000..cc6c66cd --- /dev/null +++ b/Firmware/optiboot_w25x20cl.cpp @@ -0,0 +1,310 @@ +// Based on the OptiBoot project +// https://github.com/Optiboot/optiboot +// Licence GLP 2 or later. + +#include "Marlin.h" +#include "w25x20cl.h" +#include "stk500.h" +#include "bootapp.h" + +#define OPTIBOOT_MAJVER 6 +#define OPTIBOOT_CUSTOMVER 0 +#define OPTIBOOT_MINVER 2 +static unsigned const int __attribute__((section(".version"))) + 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 +#define W25X20CL_SIGNATURE_0 9 +#define W25X20CL_SIGNATURE_1 8 +#define W25X20CL_SIGNATURE_2 7 +#else +//FIXME this is a signature of ATmega2560! +#define W25X20CL_SIGNATURE_0 0x1E +#define W25X20CL_SIGNATURE_1 0x98 +#define W25X20CL_SIGNATURE_2 0x01 +#endif + +static void watchdogConfig(uint8_t x) { + WDTCSR = _BV(WDCE) | _BV(WDE); + WDTCSR = x; +} + +static void watchdogReset() { + __asm__ __volatile__ ( + "wdr\n" + ); +} + +#define RECV_READY ((UCSR0A & _BV(RXC0)) != 0) + +static uint8_t getch(void) { + uint8_t ch; + while(! RECV_READY) ; + if (!(UCSR0A & _BV(FE0))) { + /* + * A Framing Error indicates (probably) that something is talking + * to us at the wrong bit rate. Assume that this is because it + * expects to be talking to the application, and DON'T reset the + * watchdog. This should cause the bootloader to abort and run + * the application "soon", if it keeps happening. (Note that we + * don't care that an invalid char is returned...) + */ + watchdogReset(); + } + ch = UDR0; + return ch; +} + +static void putch(char ch) { + while (!(UCSR0A & _BV(UDRE0))); + UDR0 = ch; +} + +static void verifySpace() { + if (getch() != CRC_EOP) { + putch(STK_FAILED); + watchdogConfig(WATCHDOG_16MS); // shorten WD timeout + while (1) // and busy-loop so that WD causes + ; // a reset and app start. + } + putch(STK_INSYNC); +} + +static void getNch(uint8_t count) { + do getch(); while (--count); + verifySpace(); +} + +typedef uint16_t pagelen_t; + +static const char entry_magic_send [] PROGMEM = "start\n"; +static const char entry_magic_receive[] PROGMEM = "w25x20cl_enter\n"; +static const char entry_magic_cfm [] PROGMEM = "w25x20cl_cfm\n"; + +struct block_t; +extern struct block_t *block_buffer; + +void optiboot_w25x20cl_enter() +{ + if (boot_app_flags & BOOT_APP_FLG_USER0) return; + uint8_t ch; + uint8_t rampz = 0; + register uint16_t address = 0; + register pagelen_t length; + // Use the planner's queue for the receive / transmit buffers. +// uint8_t *buff = (uint8_t*)block_buffer; + uint8_t buff[260]; + // bitmap of pages to be written. Bit is set to 1 if the page has already been erased. + uint8_t pages_erased = 0; + + // Handshake sequence: Initialize the serial line, flush serial line, send magic, receive magic. + // If the magic is not received on time, or it is not received correctly, continue to the application. + { + watchdogReset(); + unsigned long boot_timeout = 2000000; + unsigned long boot_timer = 0; + const char *ptr = entry_magic_send; + const char *end = strlen_P(entry_magic_send) + ptr; + // Initialize the serial line. + UCSR0A |= (1 << U2X0); + UBRR0L = (((float)(F_CPU))/(((float)(115200))*8.0)-1.0+0.5); + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + // Flush the serial line. + while (RECV_READY) { + watchdogReset(); + // Dummy register read (discard) + (void)(*(char *)UDR0); + } + // Send the initial magic string. + while (ptr != end) + putch(pgm_read_byte_far(ptr ++)); + watchdogReset(); + // Wait for one second until a magic string (constant entry_magic) is received + // from the serial line. + ptr = entry_magic_receive; + end = strlen_P(entry_magic_receive) + ptr; + while (ptr != end) { + while (! RECV_READY) { + watchdogReset(); + delayMicroseconds(1); + if (++ boot_timer > boot_timeout) + // Timeout expired, continue with the application. + return; + } + ch = UDR0; + if (pgm_read_byte_far(ptr ++) != ch) + // Magic was not received correctly, continue with the application + return; + watchdogReset(); + } + // Send the cfm magic string. + ptr = entry_magic_cfm; + while (ptr != end) + putch(pgm_read_byte_far(ptr ++)); + } + + spi_init(); + w25x20cl_init(); + watchdogConfig(WATCHDOG_OFF); + + /* Forever loop: exits by causing WDT reset */ + for (;;) { + /* get character from UART */ + ch = getch(); + + if(ch == STK_GET_PARAMETER) { + unsigned char which = getch(); + verifySpace(); + /* + * Send optiboot version as "SW version" + * Note that the references to memory are optimized away. + */ + if (which == STK_SW_MINOR) { + putch(optiboot_version & 0xFF); + } else if (which == STK_SW_MAJOR) { + putch(optiboot_version >> 8); + } else { + /* + * GET PARAMETER returns a generic 0x03 reply for + * other parameters - enough to keep Avrdude happy + */ + putch(0x03); + } + } + else if(ch == STK_SET_DEVICE) { + // SET DEVICE is ignored + getNch(20); + } + else if(ch == STK_SET_DEVICE_EXT) { + // SET DEVICE EXT is ignored + getNch(5); + } + else if(ch == STK_LOAD_ADDRESS) { + // LOAD ADDRESS + uint16_t newAddress; + // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter. + // Send the binary data by nibbles to avoid transmitting the ';' character. + newAddress = getch(); + newAddress |= getch(); + newAddress |= (((uint16_t)getch()) << 8); + newAddress |= (((uint16_t)getch()) << 8); + // Transfer top bit to LSB in rampz + if (newAddress & 0x8000) + rampz |= 0x01; + else + rampz &= 0xFE; + newAddress += newAddress; // Convert from word address to byte address + address = newAddress; + verifySpace(); + } + else if(ch == STK_UNIVERSAL) { + // LOAD_EXTENDED_ADDRESS is needed in STK_UNIVERSAL for addressing more than 128kB + if ( AVR_OP_LOAD_EXT_ADDR == getch() ) { + // get address + getch(); // get '0' + rampz = (rampz & 0x01) | ((getch() << 1) & 0xff); // get address and put it in rampz + getNch(1); // get last '0' + // response + putch(0x00); + } + else { + // everything else is ignored + getNch(3); + putch(0x00); + } + } + /* Write memory, length is big endian and is in bytes */ + else if(ch == STK_PROG_PAGE) { + // PROGRAM PAGE - we support flash programming only, not EEPROM + uint8_t desttype; + uint8_t *bufPtr; + pagelen_t savelength; + // Read the page length, with the length transferred each nibble separately to work around + // the Prusa's USB to serial infamous semicolon issue. + length = ((pagelen_t)getch()) << 8; + length |= ((pagelen_t)getch()) << 8; + length |= getch(); + length |= getch(); + + savelength = length; + // Read the destination type. It should always be 'F' as flash. + desttype = getch(); + + // read a page worth of contents + bufPtr = buff; + do *bufPtr++ = getch(); + while (--length); + + // Read command terminator, start reply + verifySpace(); + if (desttype == 'E') { + while (1) ; // Error: wait for WDT + } else { + uint32_t addr = (((uint32_t)rampz) << 16) | address; + // During a single bootloader run, only erase a 64kB block once. + // An 8bit bitmask 'pages_erased' covers 512kB of FLASH memory. + if (address == 0 && (pages_erased & (1 << addr)) == 0) { + w25x20cl_wait_busy(); + w25x20cl_enable_wr(); + w25x20cl_block64_erase(addr); + pages_erased |= (1 << addr); + } + w25x20cl_wait_busy(); + w25x20cl_enable_wr(); + w25x20cl_page_program(addr, buff, savelength); + w25x20cl_wait_busy(); + w25x20cl_disable_wr(); + } + } + /* Read memory block mode, length is big endian. */ + else if(ch == STK_READ_PAGE) { + uint32_t addr = (((uint32_t)rampz) << 16) | address; + uint8_t desttype; + register pagelen_t i; + // Read the page length, with the length transferred each nibble separately to work around + // the Prusa's USB to serial infamous semicolon issue. + length = ((pagelen_t)getch()) << 8; + length |= ((pagelen_t)getch()) << 8; + length |= getch(); + length |= getch(); + // Read the destination type. It should always be 'F' as flash. + desttype = getch(); + verifySpace(); + w25x20cl_wait_busy(); + w25x20cl_rd_data(addr, buff, length); + for (i = 0; i < length; ++ i) + putch(buff[i]); + } + /* Get device signature bytes */ + else if(ch == STK_READ_SIGN) { + // READ SIGN - return what Avrdude wants to hear + verifySpace(); + putch(W25X20CL_SIGNATURE_0); + putch(W25X20CL_SIGNATURE_1); + putch(W25X20CL_SIGNATURE_2); + } + else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ + // Adaboot no-wait mod + watchdogConfig(WATCHDOG_16MS); + verifySpace(); + } + else { + // This covers the response to commands like STK_ENTER_PROGMODE + verifySpace(); + } + putch(STK_OK); + } +} diff --git a/Firmware/optiboot_w25x20cl.h b/Firmware/optiboot_w25x20cl.h new file mode 100644 index 00000000..dc7d4395 --- /dev/null +++ b/Firmware/optiboot_w25x20cl.h @@ -0,0 +1,6 @@ +#ifndef OPTIBOOT_W25X20CL_H +#define OPTIBOOT_W25X20CL_H + +extern void optiboot_w25x20cl_enter(); + +#endif /* OPTIBOOT_W25X20CL_H */ diff --git a/Firmware/stk500.h b/Firmware/stk500.h new file mode 100644 index 00000000..ee1a17fd --- /dev/null +++ b/Firmware/stk500.h @@ -0,0 +1,49 @@ +/* STK500 constants list, from AVRDUDE + * + * Trivial set of constants derived from Atmel App Note AVR061 + * Not copyrighted. Released to the public domain. + */ + +#define STK_OK 0x10 +#define STK_FAILED 0x11 // Not used +#define STK_UNKNOWN 0x12 // Not used +#define STK_NODEVICE 0x13 // Not used +#define STK_INSYNC 0x14 // ' ' +#define STK_NOSYNC 0x15 // Not used +#define ADC_CHANNEL_ERROR 0x16 // Not used +#define ADC_MEASURE_OK 0x17 // Not used +#define PWM_CHANNEL_ERROR 0x18 // Not used +#define PWM_ADJUST_OK 0x19 // Not used +#define CRC_EOP 0x20 // 'SPACE' +#define STK_GET_SYNC 0x30 // '0' +#define STK_GET_SIGN_ON 0x31 // '1' +#define STK_SET_PARAMETER 0x40 // '@' +#define STK_GET_PARAMETER 0x41 // 'A' +#define STK_SET_DEVICE 0x42 // 'B' +#define STK_SET_DEVICE_EXT 0x45 // 'E' +#define STK_ENTER_PROGMODE 0x50 // 'P' +#define STK_LEAVE_PROGMODE 0x51 // 'Q' +#define STK_CHIP_ERASE 0x52 // 'R' +#define STK_CHECK_AUTOINC 0x53 // 'S' +#define STK_LOAD_ADDRESS 0x55 // 'U' +#define STK_UNIVERSAL 0x56 // 'V' +#define STK_PROG_FLASH 0x60 // '`' +#define STK_PROG_DATA 0x61 // 'a' +#define STK_PROG_FUSE 0x62 // 'b' +#define STK_PROG_LOCK 0x63 // 'c' +#define STK_PROG_PAGE 0x64 // 'd' +#define STK_PROG_FUSE_EXT 0x65 // 'e' +#define STK_READ_FLASH 0x70 // 'p' +#define STK_READ_DATA 0x71 // 'q' +#define STK_READ_FUSE 0x72 // 'r' +#define STK_READ_LOCK 0x73 // 's' +#define STK_READ_PAGE 0x74 // 't' +#define STK_READ_SIGN 0x75 // 'u' +#define STK_READ_OSCCAL 0x76 // 'v' +#define STK_READ_FUSE_EXT 0x77 // 'w' +#define STK_READ_OSCCAL_EXT 0x78 // 'x' +#define STK_SW_MAJOR 0x81 // ' ' +#define STK_SW_MINOR 0x82 // ' ' + +/* AVR raw commands sent via STK_UNIVERSAL */ +#define AVR_OP_LOAD_EXT_ADDR 0x4d diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 92f7f23f..53a53d20 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -27,23 +27,6 @@ #endif //TMC2130 -#include - -int lcd_puts_P(const char* str) -{ - return fputs_P(str, lcdout); -} - -int lcd_printf_P(const char* format, ...) -{ - va_list args; - va_start(args, format); - int ret = vfprintf_P(lcdout, format, args); - va_end(args); - return ret; -} - - int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */ extern int lcd_change_fil_state; @@ -315,7 +298,6 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l #endif #endif - /* Helper macros for menus */ #define START_MENU() do { \ if (encoderPosition > 0x8000) encoderPosition = 0; \ @@ -427,6 +409,48 @@ static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const boo /* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */ +#include + +int lcd_puts_P(const char* str) +{ + return fputs_P(str, lcdout); +} + +int lcd_printf_P(const char* format, ...) +{ + va_list args; + va_start(args, format); + int ret = vfprintf_P(lcdout, format, args); + va_end(args); + return ret; +} + +#ifdef DEBUG_MENU_PRINTF_TEST +int menu_item_printf_P(uint8_t& item, uint8_t line, const char* format, ...) +{ + va_list args; + va_start(args, format); + int ret = 0; + if (item == line) + { + if (lcdDrawUpdate) + { + //ret = + lcd.setCursor(0, line); + lcd.print(' '); + int cnt = vfprintf_P(lcdout, format, args); + for (int i = cnt; i < 19; i++) + lcd.print(' '); + lcd.print('>'); + } + } + item++; + va_end(args); + return ret; +} +#endif //DEBUG_MENU_PRINTF_TEST + + static void lcd_status_screen() { if (firstrun == 1) @@ -3682,11 +3706,18 @@ void lcd_set_progress() { static void lcd_language_menu() { START_MENU(); - if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); - MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); -// MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1); - for (int i = 2; i < lang_get_count(); i++) //skip seconday language - solved in lang_select - MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i); + if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); // + MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); //primary language + uint8_t cnt = lang_get_count(); +#ifdef W25X20CL + if (cnt == 2) //display secondary language in case of clear xflash + MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1); + else + for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select (MK3) +#else //W25X20CL + for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25) +#endif //W25X20CL + MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i); END_MENU(); } #endif //(LANG_MODE != 0) @@ -4149,11 +4180,11 @@ static void lcd_settings_menu() } #ifdef TMC2130_LINEARITY_CORRECTION_XYZ -// MENU_ITEM_EDIT(wfac, _i("X-corr"), &tmc2130_wave_fac[X_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 -// MENU_ITEM_EDIT(wfac, _i("Y-corr"), &tmc2130_wave_fac[Y_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 -// MENU_ITEM_EDIT(wfac, _i("Z-corr"), &tmc2130_wave_fac[Z_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT(wfac, _i("X-correct"), &tmc2130_wave_fac[X_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT(wfac, _i("Y-correct"), &tmc2130_wave_fac[Y_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT(wfac, _i("Z-correct"), &tmc2130_wave_fac[Z_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 #endif //TMC2130_LINEARITY_CORRECTION_XYZ -// MENU_ITEM_EDIT(wfac, _i("E-corr"), &tmc2130_wave_fac[E_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 + MENU_ITEM_EDIT(wfac, _i("E-correct"), &tmc2130_wave_fac[E_AXIS], TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);////MSG_EXTRUDER_CORRECTION c=9 r=0 #endif //TMC2130 if (temp_cal_active == false) { @@ -5582,6 +5613,10 @@ static void lcd_main_menu() MENU_ITEM(submenu, _i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0 MENU_ITEM(submenu, _i("W25x20XL init"), lcd_test_menu);////MSG_SUPPORT c=0 r=0 +#ifdef DEBUG_MENU_PRINTF_TEST + menu_item_printf_P(_menuItemNr, _lineNr, _N("Test %d %d %d"), 0, 1, 2); +#endif //DEBUG_MENU_PRINTF_TEST + END_MENU(); } @@ -6059,7 +6094,7 @@ char *wfac_to_str5(const uint8_t &x) conv[0] = '['; ftostr43(((float)((uint16_t)x + 1000) / 1000), 1); } - else strcpy_P(conv, _i(" [off"));////MSG_EXTRUDER_CORRECTION_OFF c=6 r=0 + else strncpy_P(conv, _i(" [off"), 6);////MSG_EXTRUDER_CORRECTION_OFF c=6 r=0 conv[6] = ']'; conv[7] = ' '; conv[8] = 0; diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index d366d429..c7e9e59e 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -422,6 +422,10 @@ THERMISTORS SETTINGS #define END_FILE_SECTION 10000 //number of bytes from end of file used for checking if file is complete +// Safety timer +#define SAFETYTIMER +#define DEFAULT_SAFETYTIMER_TIME_MINS 30 + #define M600_TIMEOUT 600 //seconds #ifndef SNMM diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index df676383..022c3293 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -422,6 +422,10 @@ THERMISTORS SETTINGS #define END_FILE_SECTION 10000 //number of bytes from end of file used for checking if file is complete +// Safety timer +#define SAFETYTIMER +#define DEFAULT_SAFETYTIMER_TIME_MINS 30 + #define M600_TIMEOUT 600 //seconds #ifndef SNMM diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index c7e1421b..d07ab986 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -106,6 +106,7 @@ // Safety timer #define SAFETYTIMER +#define DEFAULT_SAFETYTIMER_TIME_MINS 30 // Filament sensor #define PAT9125 diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index a8f07916..d019c758 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -106,6 +106,7 @@ // Safety timer #define SAFETYTIMER +#define DEFAULT_SAFETYTIMER_TIME_MINS 30 // Filament sensor #define PAT9125 diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index d78a737c..4c9f2433 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -130,6 +130,7 @@ // Safety timer #define SAFETYTIMER +#define DEFAULT_SAFETYTIMER_TIME_MINS 30 // Filament sensor #define PAT9125 @@ -148,6 +149,7 @@ //#define DEBUG_BUILD //#define DEBUG_SEC_LANG //secondary language debug output at startup //#define DEBUG_W25X20CL //debug external spi flash +//#define DEBUG_MENU_PRINTF_TEST #ifdef DEBUG_BUILD //#define _NO_ASM #define DEBUG_DCODES //D codes diff --git a/Firmware/w25x20cl.c b/Firmware/w25x20cl.c index 611897fe..79467cb6 100644 --- a/Firmware/w25x20cl.c +++ b/Firmware/w25x20cl.c @@ -122,7 +122,7 @@ void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt) void w25x20cl_erase(uint8_t cmd, uint32_t addr) { _CS_LOW(); - _SPI_TX(_CMD_SECTOR_ERASE); // send command 0x20 + _SPI_TX(cmd); // send command 0x20 _SPI_TX(((uint8_t*)&addr)[2]); // send addr bits 16..23 _SPI_TX(((uint8_t*)&addr)[1]); // send addr bits 8..15 _SPI_TX(((uint8_t*)&addr)[0]); // send addr bits 0..7 @@ -177,3 +177,8 @@ int w25x20cl_mfrid_devid(void) _CS_HIGH(); return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID)); } + +void w25x20cl_wait_busy(void) +{ + while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ; +} diff --git a/Firmware/w25x20cl.h b/Firmware/w25x20cl.h index 8a0ed0ac..10aaaf2c 100644 --- a/Firmware/w25x20cl.h +++ b/Firmware/w25x20cl.h @@ -34,8 +34,9 @@ extern void w25x20cl_sector_erase(uint32_t addr); extern void w25x20cl_block32_erase(uint32_t addr); extern void w25x20cl_block64_erase(uint32_t addr); extern void w25x20cl_chip_erase(void); +extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt); extern void w25x20cl_rd_uid(uint8_t* uid); - +extern void w25x20cl_wait_busy(void); #if defined(__cplusplus) } diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 2b1068e4..a6a23335 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -1,6 +1,6 @@ #MSG_EXTRUDER_CORRECTION_OFF c=6 r=0 " [off" -"[inactivo" +" [ina" #MSG_PLANNER_BUFFER_BYTES c=0 r=0 " PlannerBufferBytes: " @@ -196,7 +196,7 @@ #MSG_CRASHDETECT_OFF c=0 r=0 "Crash det. [off]" -"Det. choque [inactivo]" +"Det. choque [ina]" #MSG_CRASH_DETECTED c=20 r=1 "Crash detected." @@ -588,19 +588,19 @@ #MSG_STEALTH_MODE_OFF c=0 r=0 "Mode [Normal]" -"Modo [Normal]" +"Modo [Normal]" #MSG_SILENT_MODE_ON c=0 r=0 "Mode [silent]" -"Modo [silencio]" +"Modo [silencio]" #MSG_STEALTH_MODE_ON c=0 r=0 "Mode [Stealth]" -"Modo [Silencio]" +"Modo [Silencio]" #MSG_AUTO_MODE_ON c=0 r=0 "Mode [auto power]" -"Modo [fuerza auto]" +"Modo[fuerza auto]" #MSG_SILENT_MODE_OFF c=0 r=0 "Mode [high power]" @@ -864,7 +864,7 @@ #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1 "SD card [FlshAir]" -"Tarj. SD [FlshAir]" +"Tarj.SD [FlshAir]" #MSG_SD_CARD_OK c=0 r=0 "SD card ok" @@ -892,11 +892,11 @@ #MSG_SELFTEST_START c=20 r=0 "Self test start " -"Iniciar Selftest" +"Iniciar Selftest " #MSG_SELFTEST c=0 r=0 "Selftest " -"Selftest" +"Selftest " #MSG_SELFTEST_ERROR c=0 r=0 "Selftest error !" @@ -904,7 +904,7 @@ #MSG_SELFTEST_FAILED c=20 r=0 "Selftest failed " -"Fallo Selftest" +"Fallo Selftest " #MSG_FORCE_SELFTEST c=20 r=8 "Selftest will be run to calibrate accurate sensorless rehoming." @@ -936,11 +936,11 @@ #MSG_SORT_TIME c=17 r=1 "Sort: [Time]" -"Orden: [Fecha]" +"Orden: [Fecha]" #MSG_SORT_ALPHA c=17 r=1 "Sort: [Alphabet]" -"Orden: [Alfabético]" +"Orden:[Alfabétic]" #MSG_SORTING c=20 r=1 "Sorting files" @@ -988,11 +988,11 @@ #MSG_TEMP_CALIBRATION_ON c=20 r=1 "Temp. cal. [on]" -"Cal. temp. [ON]" +"Cal. temp. [ON]" #MSG_TEMP_CALIBRATION_OFF c=20 r=1 "Temp. cal. [off]" -"Cal. temp. [OFF]" +"Cal. temp. [OFF]" #MSG_CALIBRATION_PINDA_MENU c=17 r=1 "Temp. calibration" diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index 7aba7dfd..13a047b6 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -12,11 +12,11 @@ #MSG_FREE_MEMORY c=0 r=0 " Free Memory: " -"\x00" +"Memoria Libera: " #MSG_CONFIGURATION_VER c=0 r=0 " Last Updated: " -"\x00" +"Ultimo aggiornamento: " #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0 " of 4" @@ -24,11 +24,11 @@ #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 " of 9" -" su 9" +"su 9" #MSG_MEASURED_OFFSET c=0 r=0 "[0;0] point offset" -"\x00" +"[0;0] punto offset" #MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4 "\x1b[2JCrash detection can\x1b[1;0Hbe turned on only in\x1b[2;0HNormal mode" @@ -52,7 +52,7 @@ #MSG_WIZARD_DONE c=20 r=8 "All is done. Happy printing!" -"Ben fatto. Buona stampa!" +"Tutto fatto. Buona stampa!" #MSG_PRESS c=20 r=0 "and press the knob" @@ -72,23 +72,23 @@ #MSG_AUTOLOAD_FILAMENT c=17 r=0 "AutoLoad filament" -"\x00" +"Autocaricamento filamento" #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4 "Autoloading filament available only when filament sensor is turned on..." -"\x00" +"Il caricamento automatico del filamento è disponibile solo quando il sensore è acceso..." #MSG_AUTOLOADING_ENABLED c=20 r=4 "Autoloading filament is active, just press the knob and insert filament..." -"\x00" +"Il caricamento automatico è attivo, premete la manopola e inserite il filamento..." #MSG_SELFTEST_AXIS_LENGTH c=0 r=0 "Axis length" -"\x00" +"Lunghezza dell'asse" #MSG_SELFTEST_AXIS c=0 r=0 "Axis" -"\x00" +"Assi" #MSG_SELFTEST_BEDHEATER c=0 r=0 "Bed / Heater" @@ -96,7 +96,7 @@ #MSG_BED_DONE c=0 r=0 "Bed done" -"Piatto fatto." +"Piano fatto." #MSG_BED_HEATING c=0 r=0 "Bed Heating" @@ -108,15 +108,15 @@ #MSG_BED_LEVELING_FAILED_POINT_LOW c=20 r=4 "Bed leveling failed. Sensor didnt trigger. Debris on nozzle? Waiting for reset." -"Livellamento letto fallito.NoRispSensor Residui su ugello? In attesa di reset." +"Livellamento letto fallito.NoRispSensore.Residui su ugello? In attesa di reset." #MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED c=20 r=4 "Bed leveling failed. Sensor disconnected or cable broken. Waiting for reset." -"Livellamento letto fallito. Sensore discon. o Cavo Dann. In attesa di reset." +"Livellamento piano fallito. Sensore disconnesso o Cavo Danneggiato. In attesa di reset." #MSG_BED_LEVELING_FAILED_POINT_HIGH c=20 r=4 "Bed leveling failed. Sensor triggered too high. Waiting for reset." -"Livellamento letto fallito.Risp sensore troppo prestoIn attesa di reset." +"Livellamento piano fallito. Risposta sensore troppo presto. In attesa di reset." #MSG_BED c=0 r=0 "Bed" @@ -124,15 +124,15 @@ #MSG_BEGIN_FILE_LIST c=0 r=0 "Begin file list" -"\x00" +"Inizio lista file" #MSG_MENU_BELT_STATUS c=15 r=1 "Belt status" -"\x00" +"Stato delle cinghie" #MSG_RECOVER_PRINT c=20 r=2 "Blackout occurred. Recover print?" -"\x00" +"C'è stato un Blackout. Recuperare la stampa?" #MSG_CALIBRATE_BED c=0 r=0 "Calibrate XYZ" @@ -144,7 +144,7 @@ #MSG_CALIBRATE_PINDA c=17 r=1 "Calibrate" -"Calibrare" +"Calibra" #MSG_MOVE_CARRIAGE_TO_THE_TOP c=20 r=8 "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." @@ -160,7 +160,7 @@ #MSG_HOMEYZ_DONE c=0 r=0 "Calibration done" -"Calibrazione OK" +"Calibrazione completa" #MSG_MENU_CALIBRATION c=0 r=0 "Calibration" @@ -168,7 +168,7 @@ #MSG_SD_CANT_ENTER_SUBDIR c=0 r=0 "Cannot enter subdir: " -"\x00" +"Impossibile accedere alla sottocartella: " #MSG_SD_INSERTED c=0 r=0 "Card inserted" @@ -188,19 +188,19 @@ #MSG_CRASHDETECT_ON c=0 r=0 "Crash det. [on]" -"\x00" +"Rilevamento imp. [on]" #MSG_CRASHDETECT_NA c=0 r=0 "Crash det. [N/A]" -"\x00" +"Rilevamento imp. [N/A]" #MSG_CRASHDETECT_OFF c=0 r=0 "Crash det. [off]" -"\x00" +"Rilevamento imp. [off]" #MSG_CRASH_DETECTED c=20 r=1 "Crash detected." -"\x00" +"Rilevato impatto." #MSG_CURRENT c=19 r=1 "Current" @@ -208,15 +208,15 @@ #MSG_DATE c=17 r=1 "Date:" -"Data" +"Data:" #MSG_DISABLE_STEPPERS c=0 r=0 "Disable steppers" -"Disabilit motori" +"Disabilita motori" #MSG_BABYSTEP_Z_NOT_SET c=20 r=12 "Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration." -"Distanza tra la punta dell'ugello e la superficie del letto non ancora imposta. Si prega di seguire il manuale, capitolo First steps, sezione First layer calibration." +"Distanza tra la punta dell'ugello e la superficie del letto non ancora imposta. Si prega di seguire il manuale, capitolo Primi Passi, sezione Calibrazione primo layer." #MSG_WIZARD_REPEAT_V2_CAL c=20 r=7 "Do you want to repeat last step to readjust distance between nozzle and heatbed?" @@ -224,11 +224,11 @@ #MSG_EXTRUDER_CORRECTION c=9 r=0 "E-correct" -"\x00" +"Correzione-E" #MSG_END_FILE_LIST c=0 r=0 "End file list" -"\x00" +"Fine lista file" #MSG_SELFTEST_ENDSTOP_NOTHIT c=20 r=1 "Endstop not hit" @@ -240,11 +240,11 @@ #MSG_ENDSTOPS_HIT c=0 r=0 "endstops hit: " -"\x00" +"finecorsa colpito: " #MSG_SELFTEST_ENDSTOPS c=0 r=0 "Endstops" -"Finecorsa (2)" +"Finecorsa" #MSG_Enqueing c=0 r=0 "enqueing \x22" @@ -252,15 +252,15 @@ #MSG_STACK_ERROR c=20 r=4 "Error - static memory has been overwritten" -"\x00" +"Errore - la memoria statica è stata sovrascritta" #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0 "error writing to file" -"\x00" +"errore scrittura sul file" #MSG_FSENS_NOT_RESPONDING c=20 r=4 "ERROR: Filament sensor is not responding, please check connection." -"\x00" +"ERRORE: il sensore del filamento non risponde, per favore controllate la connessione" #MSG_ERROR c=0 r=0 "ERROR:" @@ -268,59 +268,59 @@ #MSG_SELFTEST_EXTRUDER_FAN_SPEED c=18 r=0 "Extruder fan:" -"\x00" +"Ventola estrusore:" #MSG_INFO_EXTRUDER c=15 r=1 "Extruder info" -"\x00" +"Info estrusore" #MSG_MOVE_E c=0 r=0 "Extruder" -"Muovi Estrusore" +"Estrusore" #MSG_FSENS_AUTOLOAD_ON c=17 r=1 "F. autoload [on]" -"\x00" +"Autocaricamento f. [on]" #MSG_FSENS_AUTOLOAD_NA c=17 r=1 "F. autoload [N/A]" -"\x00" +"Autocaricamento f. [N/A]" #MSG_FSENS_AUTOLOAD_OFF c=17 r=1 "F. autoload [off]" -"\x00" +"Autocaricamento f. [off]" #MSG_FAN_SPEED c=14 r=0 "Fan speed" -"Velocita vent." +"Velocità ventola" #MSG_SELFTEST_FAN c=20 r=0 "Fan test" -"Prova del ventilator" +"Test ventola" #MSG_FANS_CHECK_ON c=17 r=1 "Fans check [on]" -"\x00" +"Controllo ventole [on]" #MSG_FANS_CHECK_OFF c=17 r=1 "Fans check [off]" -"\x00" +"Controllo ventole [off]" #MSG_FSENSOR_ON c=0 r=0 "Fil. sensor [on]" -"\x00" +"Sensore filamenti [On]" #MSG_FSENSOR_NA c=0 r=0 "Fil. sensor [N/A]" -"\x00" +"Sensore fil. [N/A]" #MSG_FSENSOR_OFF c=0 r=0 "Fil. sensor [off]" -"\x00" +"Sensore filamenti [off]" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" -"Il colore e' nitido?" +"Filamento estruso & con il giusto colore?" #MSG_NOT_LOADED c=19 r=0 "Filament not loaded" @@ -328,35 +328,35 @@ #MSG_FILAMENT_SENSOR c=20 r=0 "Filament sensor" -"\x00" +"Sensore filamento " #MSG_SELFTEST_FILAMENT_SENSOR c=18 r=0 "Filament sensor:" -"\x00" +"Sensore del filamento:" #MSG_FILE_INCOMPLETE c=20 r=2 "File incomplete. Continue anyway?" -"\x00" +"File incompleto. Continuare comunque?" #MSG_SD_FILE_OPENED c=0 r=0 "File opened: " -"\x00" +"File aperto: " #MSG_SD_FILE_SELECTED c=0 r=0 "File selected" -"\x00" +"File selezionato" #MSG_FINISHING_MOVEMENTS c=20 r=1 "Finishing movements" -"Arresto in corso" +"Finalizzando gli spostamenti" #MSG_V2_CALIBRATION c=17 r=1 "First layer cal." -"Cal. primo layer." +"Calibrazione primo layer." #MSG_WIZARD_SELFTEST c=20 r=8 "First, I will run the selftest to check most common assembly problems." -"Anzitutto avviero il Self Test per controllare gli errori di assemblaggio piu comuni." +"Per primo avvierò l'autotest per controllare gli errori di assemblaggio più comuni." #MSG_FLOW c=0 r=0 "Flow" @@ -368,7 +368,7 @@ #MSG_SELFTEST_COOLING_FAN c=20 r=0 "Front print fan?" -"Vent di stampa ant.?" +"Ventola di stampa frontale?" #MSG_BED_CORRECTION_FRONT c=14 r=1 "Front side[um]" @@ -376,7 +376,7 @@ #MSG_SELFTEST_FANS c=0 r=0 "Front/left fans" -"\x00" +"Ventola frontale/sinistra" #MSG_SELFTEST_HEATERTHERMISTOR c=0 r=0 "Heater/Thermistor" @@ -384,7 +384,7 @@ #MSG_BED_HEATING_SAFETY_DISABLED c=0 r=0 "Heating disabled by safety timer." -"\x00" +"Riscaldamento fermato dal timer di sicurezza." #MSG_HEATING_COMPLETE c=20 r=0 "Heating done." @@ -396,7 +396,7 @@ #MSG_WIZARD_WELCOME c=20 r=7 "Hi, I am your Original Prusa i3 printer. Would you like me to guide you through the setup process?" -"Ciao, sono la tua stampante Original Prusa i3. Gradiresti aiuto attraverso il processo di configurazione?" +"Ciao, sono la tua stampante Original Prusa i3. Gradiresti un aiuto nel processo di configurazione?" #MSG_PRUSA3D_HOWTO c=0 r=0 "howto.prusa3d.com" @@ -404,7 +404,7 @@ #MSG_FILAMENTCHANGE c=0 r=0 "Change filament" -"Camb. filamento" +"Cambia filamento" #MSG_CHANGE_SUCCESS c=0 r=0 "Change success!" @@ -412,7 +412,7 @@ #MSG_CORRECTLY c=20 r=0 "Changed correctly?" -"Cambiato corr.?" +"Cambiato correttamente?" #MSG_CHANGING_FILAMENT c=20 r=0 "Changing filament!" @@ -420,7 +420,7 @@ #MSG_SELFTEST_CHECK_BED c=20 r=0 "Checking bed " -"Verifica letto" +"Verifica piano" #MSG_SELFTEST_CHECK_ENDSTOPS c=20 r=0 "Checking endstops" @@ -432,7 +432,7 @@ #MSG_SELFTEST_CHECK_FSENSOR c=20 r=0 "Checking sensors " -"\x00" +"Controllo sensori" #MSG_SELFTEST_CHECK_X c=20 r=0 "Checking X axis " @@ -456,11 +456,11 @@ #MSG_WIZARD_XYZ_CAL c=20 r=8 "I will run xyz calibration now. It will take approx. 12 mins." -"Adesso avviero una Calibrazione XYZ. Puo durare circa 12 min." +"Adesso avviero una Calibrazione XYZ. Può durare circa 12 min." #MSG_WIZARD_Z_CAL c=20 r=8 "I will run z calibration now." -"Adesso avviero una Calibrazione Z." +"Adesso avvierò la Calibrazione Z." #MSG_WIZARD_V2_CAL_2 c=20 r=12 "I will start to print line and you will gradually lower the nozzle by rotating the knob, until you reach optimal height. Check the pictures in our handbook in chapter Calibration." @@ -480,7 +480,7 @@ #MSG_FILAMENT_LOADING_T1 c=20 r=4 "Insert filament into extruder 2. Click when done." -"Inserire filamento nell'estrusore 2. Click per continuare." +"Inserire filamento nell'estrusore 2. Clicca per continuare." #MSG_FILAMENT_LOADING_T2 c=20 r=4 "Insert filament into extruder 3. Click when done." @@ -488,7 +488,7 @@ #MSG_FILAMENT_LOADING_T3 c=20 r=4 "Insert filament into extruder 4. Click when done." -"Inserire filamento nell'estrusore 4. Click per continuare." +"Inserire filamento nell'estrusore 4. Clicca per continuare." #MSG_INSERT_FILAMENT c=20 r=0 "Insert filament" @@ -500,19 +500,19 @@ #MSG_WIZARD_PLA_FILAMENT c=20 r=2 "Is it PLA filament?" -"E questo un filamento di PLA?" +"E' un filamento di PLA?" #MSG_PLA_FILAMENT_LOADED c=20 r=2 "Is PLA filament loaded?" -"Il PLA e stato caricato?" +"E' stato caricato il filamento di PLA?" #MSG_STEEL_SHEET_CHECK c=20 r=2 "Is steel sheet on heatbed?" -"\x00" +"La piastra d'acciaio si trova sul piano riscaldato?" #MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION c=20 r=0 "Iteration " -"Reiterazione " +"Iterazione" #MSG_KILLED c=0 r=0 "KILLED. " @@ -520,11 +520,11 @@ #MSG_SELFTEST_EXTRUDER_FAN c=20 r=0 "Left hotend fan?" -"Vent SX sull'ugello?" +"Vent SX hotend?" #MSG_BED_CORRECTION_LEFT c=14 r=1 "Left side [um]" -"Sinistra [um]" +"Lato sinistro [um]" #MSG_BABYSTEP_Z c=0 r=0 "Live adjust Z" @@ -540,7 +540,7 @@ #MSG_LOADING_FILAMENT c=20 r=0 "Loading filament" -"Caricando filam." +"Caricando filamento" #MSG_LOOSE_PULLEY c=20 r=1 "Loose pulley" @@ -548,19 +548,19 @@ #MSG_M104_INVALID_EXTRUDER c=0 r=0 "M104 Invalid extruder " -"\x00" +"M104 Estrusore non valido" #MSG_M105_INVALID_EXTRUDER c=0 r=0 "M105 Invalid extruder " -"\x00" +"M105 Estrusore non valido" #MSG_M109_INVALID_EXTRUDER c=0 r=0 "M109 Invalid extruder " -"\x00" +"M109 Estrusore non valido" #MSG_M117_V2_CALIBRATION c=25 r=1 "M117 First layer cal." -"M117 Cal. primo layer." +"M117 Calibrazione primo layer." #MSG_M200_INVALID_EXTRUDER c=0 r=0 "M200 Invalid extruder " @@ -568,11 +568,11 @@ #MSG_M218_INVALID_EXTRUDER c=0 r=0 "M218 Invalid extruder " -"\x00" +"M218 Estrusore non valido" #MSG_M221_INVALID_EXTRUDER c=0 r=0 "M221 Invalid extruder " -"\x00" +"M221 Estrusore non valido" #MSG_MAIN c=0 r=0 "Main" @@ -580,7 +580,7 @@ #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 c=60 r=0 "Measuring reference height of calibration point" -"Misurare l'altezza di riferimento del punto di calibrazione" +"Misurando altezza di riferimento del punto di calibrazione" #MSG_MESH_BED_LEVELING c=0 r=0 "Mesh Bed Leveling" @@ -588,7 +588,7 @@ #MSG_STEALTH_MODE_OFF c=0 r=0 "Mode [Normal]" -"\x00" +"Modo [normale]" #MSG_SILENT_MODE_ON c=0 r=0 "Mode [silent]" @@ -596,11 +596,11 @@ #MSG_STEALTH_MODE_ON c=0 r=0 "Mode [Stealth]" -"\x00" +"Modo [Silenziosa]" #MSG_AUTO_MODE_ON c=0 r=0 "Mode [auto power]" -"\x00" +"Modo [auto]" #MSG_SILENT_MODE_OFF c=0 r=0 "Mode [high power]" @@ -652,11 +652,11 @@ #MSG_WIZARD_V2_CAL c=20 r=8 "Now I will calibrate distance between tip of the nozzle and heatbed surface." -"Adesso tarero lo stacco fra ugello e superfice del piatto." +"Adesso calibro la distanza fra ugello e superfice del piatto." #MSG_WIZARD_WILL_PREHEAT c=20 r=4 "Now I will preheat nozzle for PLA." -"Adesso preriscaldero l'ugello per PLA." +"Adesso preriscalderò l'ugello per PLA." #MSG_NOZZLE c=0 r=0 "Nozzle" @@ -668,15 +668,15 @@ #MSG_DEFAULT_SETTINGS_LOADED c=20 r=4 "Old settings found. Default PID, Esteps etc. will be set." -"\x00" +"Sono state trovate impostazioni vecchie. I valori di default di PID, Esteps etc. saranno impostati" #MSG_SD_OPEN_FILE_FAIL c=0 r=0 "open failed, File: " -"\x00" +"apertura fallita, File: " #MSG_ENDSTOP_OPEN c=0 r=0 "open" -"\x00" +"apri" #MSG_SD_OPENROOT_FAIL c=0 r=0 "openRoot failed" @@ -688,11 +688,11 @@ #MSG_PID_RUNNING c=20 r=1 "PID cal. " -"Cal. PID" +"Calibrazione PID" #MSG_PID_FINISHED c=20 r=1 "PID cal. finished" -"Cal. PID completa" +"Calib. PID completa" #MSG_PID_EXTRUDER c=17 r=1 "PID calibration" @@ -700,7 +700,7 @@ #MSG_PINDA_PREHEAT c=20 r=1 "PINDA Heating" -"Riscald. PINDA" +"Riscaldamento PINDA" #MSG_PAPER c=20 r=8 "Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately." @@ -716,7 +716,7 @@ #MSG_SELFTEST_PLEASECHECK c=0 r=0 "Please check :" -"Verificare:" +"Verifica:" #MSG_WIZARD_CALIBRATION_FAILED c=20 r=8 "Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer." @@ -732,35 +732,35 @@ #MSG_PLEASE_LOAD_PLA c=20 r=4 "Please load PLA filament first." -"Per favore prima caricare filamento di PLA." +"Per favore prima carica il filamento di PLA." #MSG_CHECK_IDLER c=20 r=4 "Please open idler and remove filament manually." -"\x00" +"aprite l'assemblaggio estrusore e rimuovete il filamento manualmente." #MSG_PLACE_STEEL_SHEET c=20 r=4 "Please place steel sheet on heatbed." -"\x00" +"Per favore posizionate la piastra d'acciaio sul piano riscaldato." #MSG_PRESS_TO_UNLOAD c=20 r=4 "Please press the knob to unload filament" -"\x00" +"Premete la manopola per scaricare il filamento " #MSG_PULL_OUT_FILAMENT c=20 r=4 "Please pull out filament immediately" -"\x00" +"Tirate fuori il filamento immediatamente" #MSG_REMOVE_STEEL_SHEET c=20 r=4 "Please remove steel sheet from heatbed." -"\x00" +"Rimuovete la piastra di acciaio dal piano riscaldato" #MSG_PLEASE_WAIT c=20 r=0 "Please wait" -"Aspetta" +"Attendere" #MSG_POWERUP c=0 r=0 "PowerUp" -"\x00" +"Accendi" #MSG_PREHEAT_NOZZLE c=20 r=0 "Preheat the nozzle!" @@ -772,19 +772,19 @@ #MSG_WIZARD_HEATING c=20 r=3 "Preheating nozzle. Please wait." -"Sto preriscaldando l'ugello. Per favore attendi." +"Preriscaldando l'ugello. Attendere prego." #MSG_PRESS_TO_PREHEAT c=20 r=4 "Press knob to preheat nozzle and continue." -"\x00" +"Premete la manopola per preriscaldare l'ugello e continuare." #MSG_PRINT_ABORTED c=20 r=0 "Print aborted" -"Stampa abortita" +"Stampa interrotta" #MSG_SELFTEST_PRINT_FAN_SPEED c=18 r=0 "Print fan:" -"\x00" +"Ventola di stampa:" #MSG_CARD_MENU c=0 r=0 "Print from SD" @@ -800,11 +800,11 @@ #MSG_FOLLOW_CALIBRATION_FLOW c=20 r=8 "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow." -"Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione." +"Stampante non ancora calibrata. Si prega di seguire il manuale, capitolo Primi Passi, sezione Sequenza di Calibrazione." #MSG_ERR_STOPPED c=0 r=0 "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" -"\x00" +"La stampante si è fermata a causa di errori. Correggete l'errore e usate M999 per riavviare. (La temperatura viene resettate. Impostatela dopo il riavvio)" #WELCOME_MSG c=20 r=0 "Prusa i3 MK3 ready." @@ -820,7 +820,7 @@ #MSG_RECOVERING_PRINT c=20 r=1 "Recovering print " -"\x00" +"Recupero stampa" #MSG_M119_REPORT c=0 r=0 "Reporting endstop status" @@ -848,11 +848,11 @@ #MSG_SECOND_SERIAL_ON c=17 r=1 "RPi port [on]" -"\x00" +"Porta RPi [on]" #MSG_SECOND_SERIAL_OFF c=17 r=1 "RPi port [off]" -"\x00" +"Porta RPi [off]" #MSG_WIZARD_RERUN c=20 r=7 "Running Wizard will delete current calibration results and start from the beginning. Continue?" @@ -860,11 +860,11 @@ #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1 "SD card [normal]" -"SD card [normal]" +"Memoria SD [normale]" #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1 "SD card [FlshAir]" -"\x00" +"Memoria SD [FlshAir]" #MSG_SD_CARD_OK c=0 r=0 "SD card ok" @@ -872,7 +872,7 @@ #MSG_SD_INIT_FAIL c=0 r=0 "SD init fail" -"\x00" +"Inizializzazione Memoria SD Fallita" #MSG_SD_PRINTING_BYTE c=0 r=0 "SD printing byte " @@ -880,7 +880,7 @@ #MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 c=60 r=0 "Searching bed calibration point" -"Ricerca del letto punto di calibraz." +"Ricerca dei punti di calibrazione del piano" #MSG_LANGUAGE_SELECT c=0 r=0 "Select language" @@ -900,7 +900,7 @@ #MSG_SELFTEST_ERROR c=0 r=0 "Selftest error !" -"Autotest negativo" +"Errore Autotest !" #MSG_SELFTEST_FAILED c=20 r=0 "Selftest failed " @@ -908,11 +908,11 @@ #MSG_FORCE_SELFTEST c=20 r=8 "Selftest will be run to calibrate accurate sensorless rehoming." -"\x00" +"Verrà effettuato un self test per calibrare l'homing senza sensori" #MSG_SET_TEMPERATURE c=19 r=1 "Set temperature:" -"Imposta temperatura" +"Imposta temperatura:" #MSG_SETTINGS c=0 r=0 "Settings" @@ -928,27 +928,27 @@ #MSG_FILE_CNT c=20 r=4 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100." -"\x00" +"Alcuni file non saranno ordinati. Il numero massimo di file in una cartella è 100 perché siano ordinati." #MSG_SORT_NONE c=17 r=1 "Sort: [None]" -"\x00" +"Ordine: [Nessuno]" #MSG_SORT_TIME c=17 r=1 "Sort: [Time]" -"\x00" +"Ordine: [Tempo]" #MSG_SORT_ALPHA c=17 r=1 "Sort: [Alphabet]" -"\x00" +"Ordine: [Alfabetico]" #MSG_SORTING c=20 r=1 "Sorting files" -"\x00" +"Ordinando i file" #MSG_SPEED c=0 r=0 "Speed" -"Velocita" +"Velocità" #MSG_SELFTEST_FAN_YES c=19 r=0 "Spinning" @@ -956,7 +956,7 @@ #MSG_TEMP_CAL_WARNING c=20 r=4 "Stable ambient temperature 21-26C is needed a rigid stand is required." -"\x00" +"Sono necessari una temperatura ambiente di 21-26C e una superficie rigida " #MSG_STATISTICS c=0 r=0 "Statistics " @@ -964,7 +964,7 @@ #MSG_STEPPER_TOO_HIGH c=0 r=0 "Steprate too high: " -"\x00" +"Velocità passo troppo alta: " #MSG_STOP_PRINT c=0 r=0 "Stop print" @@ -976,47 +976,47 @@ #MSG_SUPPORT c=0 r=0 "Support" -"\x00" +"Supporto" #MSG_SELFTEST_SWAPPED c=0 r=0 "Swapped" -"\x00" +"Scambiato" #MSG_TEMP_CALIBRATION c=20 r=1 "Temp. cal. " -"Cal. temp. " +"Calib. temp. " #MSG_TEMP_CALIBRATION_ON c=20 r=1 "Temp. cal. [on]" -"Cal. temp. [ON]" +"Calib. temp. [ON]" #MSG_TEMP_CALIBRATION_OFF c=20 r=1 "Temp. cal. [off]" -"Cal. temp. [OFF]" +"Calib. temp. [OFF]" #MSG_CALIBRATION_PINDA_MENU c=17 r=1 "Temp. calibration" -"Taratura temp." +"Calib. Temp." #MSG_TEMP_CAL_FAILED c=20 r=8 "Temperature calibration failed" -"\x00" +"Calibrazione temperatura fallita" #MSG_TEMP_CALIBRATION_DONE c=20 r=12 "Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal." -"Taratura temperatura terminata. Fare click per continuare." +"Calibrazione temperatura completata e attiva. Può essere disattivata dal menù Impostazioni ->Cal. Temp." #MSG_TEMPERATURE c=0 r=0 "Temperature" -"Temperatura" +"\x00" #MSG_MENU_TEMPERATURES c=15 r=1 "Temperatures" -"\x00" +"Temperature" #MSG_ENDSTOP_HIT c=0 r=0 "TRIGGERED" -"\x00" +"ATTIVATO" #MSG_TUNE c=0 r=0 "Tune" @@ -1028,7 +1028,7 @@ #MSG_UNLOADING_FILAMENT c=20 r=1 "Unloading filament" -"Rilasc. filamento" +"Scaricando filamento" #MSG_USED c=19 r=1 "Used during print" @@ -1036,7 +1036,7 @@ #MSG_MENU_VOLTAGES c=15 r=1 "Voltages" -"\x00" +"Voltaggi" #MSG_SD_VOL_INIT_FAIL c=0 r=0 "volume.init failed" @@ -1044,31 +1044,31 @@ #MSG_USERWAIT c=0 r=0 "Wait for user..." -"Attendendo utente" +"Attendendo utente..." #MSG_WAITING_TEMP c=20 r=3 "Waiting for nozzle and bed cooling" -"In attesa del raffreddamento della testina e del piatto" +"In attesa del raffreddamento dell'ugello e del piano" #MSG_WAITING_TEMP_PINDA c=20 r=3 "Waiting for PINDA probe cooling" -"\x00" +"In attesa del raffreddamento della sonda PINDA" #MSG_CHANGED_BOTH c=20 r=4 "Warning: both printer type and motherboard type changed." -"\x00" +"Attenzione: tipo di stampante e di scheda madre cambiati." #MSG_CHANGED_MOTHERBOARD c=20 r=4 "Warning: motherboard type changed." -"\x00" +"Avviso: tipo di scheda madre cambiato" #MSG_CHANGED_PRINTER c=20 r=4 "Warning: printer type changed." -"\x00" +"Avviso: tipo di stampante cambiato." #MSG_UNLOAD_SUCCESSFUL c=20 r=2 "Was filament unload successful?" -"\x00" +"Filamento scaricato con successo?" #MSG_SELFTEST_WIRINGERROR c=0 r=0 "Wiring error" @@ -1084,7 +1084,7 @@ #MSG_SD_WRITE_TO_FILE c=0 r=0 "Writing to file: " -"\x00" +"Scrittura su file: " #MSG_XYZ_DETAILS c=19 r=1 "XYZ cal. details" @@ -1100,5 +1100,5 @@ #MSG_WIZARD_QUIT c=20 r=8 "You can always resume the Wizard from Calibration -> Wizard." -"E possibile proseguire la guide Wizard in qualsiasi momento attraverso Calibrazione -> Wizard." +"E possibile riprendere il Wizard in qualsiasi momento attraverso Calibrazione -> Wizard." diff --git a/lang/make_lang.sh b/lang/make_lang.sh index 261857e4..0f7bc7d4 100644 --- a/lang/make_lang.sh +++ b/lang/make_lang.sh @@ -5,18 +5,18 @@ # # Input files: # lang_en.txt -# lang_en_$LANG.txt +# lang_en_xx.txt # # Output files: # lang_en.tmp (temporary, will be removed when finished) -# lang_en_$LANG.tmp ==||== -# lang_en_$LANG.dif ==||== -# lang_$LANG.txt +# lang_en_xx.tmp ==||== +# lang_en_xx.dif ==||== +# lang_xx.txt # # # Selected language: -LANG=$1 -if [ -z "$LANG" ]; then LANG='cz'; fi +LNG=$1 +if [ -z "$LNG" ]; then LNG='cz'; fi # # @@ -24,8 +24,8 @@ finish() { if [ $1 -eq 0 ]; then if [ -e lang_en.tmp ]; then rm lang_en.tmp; fi - if [ -e lang_en_$LANG.tmp ]; then rm lang_en_$LANG.tmp; fi - if [ -e lang_en_$LANG.dif ]; then rm lang_en_$LANG.dif; fi + if [ -e lang_en_$LNG.tmp ]; then rm lang_en_$LNG.tmp; fi + if [ -e lang_en_$LNG.dif ]; then rm lang_en_$LNG.dif; fi fi # echo >&2 if [ $1 -eq 0 ]; then @@ -38,59 +38,59 @@ finish() make_lang() { -LANG=$1 +LNG=$1 echo "make_lang.sh started" >&2 -echo "selected language=$LANG" >&2 +echo "selected language=$LNG" >&2 #check if input files exists echo -n " checking input files..." >&2 if [ ! -e lang_en.txt ]; then echo "NG! file lang_en.txt not found!" >&2; exit 1; fi -if [ ! -e lang_en_$LANG.txt ]; then echo "NG! file lang_en_$LANG.txt not found!" >&2; exit 1; fi +if [ ! -e lang_en_$LNG.txt ]; then echo "NG! file lang_en_$LNG.txt not found!" >&2; exit 1; fi echo "OK" >&2 #filter comment and empty lines from key and dictionary files, create temporary files echo -n " creating tmp files..." >&2 cat lang_en.txt | sed "/^$/d;/^#/d" > lang_en.tmp -cat lang_en_$LANG.txt | sed "/^$/d;/^#/d" > lang_en_$LANG.tmp +cat lang_en_$LNG.txt | sed "/^$/d;/^#/d" > lang_en_$LNG.tmp echo "OK" >&2 -#cat lang_en_$LANG.tmp | sed 'n;d' >test1.txt +#cat lang_en_$LNG.tmp | sed 'n;d' >test1.txt #compare files using diff and check for differences echo -n " comparing tmp files..." >&2 -if ! cat lang_en_$LANG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LANG.dif; then +if ! cat lang_en_$LNG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LNG.dif; then echo "NG!" >&2 - echo "Entries in lang_en_$LANG.txt are different from lang_en.txt!" >&2 - echo "please check lang_en_$LANG.dif" >&2 + echo "Entries in lang_en_$LNG.txt are different from lang_en.txt!" >&2 + echo "please check lang_en_$LNG.dif" >&2 finish 1 fi echo "OK" >&2 #generate lang_xx.txt (secondary language text data sorted by ids) -echo -n " generating lang_$LANG.txt..." >&2 -cat lang_en_$LANG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LANG.txt +echo -n " generating lang_$LNG.txt..." >&2 +cat lang_en_$LNG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LNG.txt echo "OK" >&2 #generate lang_xx.dat (secondary language text data in binary form) -echo -n " generating lang_$LANG.dat..." >&2 -cat lang_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do +echo -n " generating lang_$LNG.dat..." >&2 +cat lang_$LNG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do s=${s#\"} s=${s%\"} /bin/echo -e -n "$s\x00" -done >lang_$LANG.dat +done >lang_$LNG.dat echo "OK" >&2 #calculate variables lt_magic='\xa5\x5a\xb4\x4b' -lt_count=$(grep -c '^' lang_$LANG.txt) -lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ') +lt_count=$(grep -c '^' lang_$LNG.txt) +lt_data_size=$(wc -c lang_$LNG.dat | cut -f1 -d' ') lt_offs_size=$((2 * $lt_count)) lt_size=$((16 + $lt_offs_size + $lt_data_size)) -lt_chsum=1 +lt_chsum=0 lt_code='\xff\xff' lt_resv1='\xff\xff\xff\xff' -case "$LANG" in +case "$LNG" in *en*) lt_code='\x6e\x65' ;; *cz*) lt_code='\x73\x63' ;; *de*) lt_code='\x65\x64' ;; @@ -100,15 +100,15 @@ case "$LANG" in esac #generate lang_xx.ofs (secondary language text data offset table) -echo -n " generating lang_$LANG.ofs..." >&2 -cat lang_$LANG.txt | sed "s/\\\\x[0-9a-f][0-9a-f]/\./g;s/\\\\[0-7][0-7][0-7]/\./g" |\ - awk 'BEGIN { o='$((16 + $lt_offs_size))';} { printf("%d\n",o); o+=(length($0)-1); }' > lang_$LANG.ofs +echo -n " generating lang_$LNG.ofs..." >&2 +cat lang_$LNG.txt | sed "s/\\\\x[0-9a-f][0-9a-f]/\./g;s/\\\\[0-7][0-7][0-7]/\./g" |\ + awk 'BEGIN { o='$((16 + $lt_offs_size))';} { printf("%d\n",o); o+=(length($0)-1); }' > lang_$LNG.ofs echo "OK" >&2 #generate lang_xx.bin (secondary language result binary file) -echo " generating lang_$LANG.bin:" >&2 +echo " generating lang_$LNG.bin:" >&2 #create empty file -dd if=/dev/zero of=lang_$LANG.bin bs=1 count=$lt_size 2>/dev/null +dd if=/dev/zero of=lang_$LNG.bin bs=1 count=$lt_size 2>/dev/null #awk code to format ui16 variables for dd awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }' @@ -116,37 +116,42 @@ awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }' echo -n " writing header (16 bytes)..." >&2 /bin/echo -n -e "$lt_magic" |\ - dd of=lang_$LANG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null /bin/echo -n -e $(echo -n "$lt_size" | awk "$awk_ui16") |\ - dd of=lang_$LANG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null /bin/echo -n -e $(echo -n "$lt_count" | awk "$awk_ui16") |\ - dd of=lang_$LANG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null /bin/echo -n -e $(echo -n "$lt_chsum" | awk "$awk_ui16") |\ - dd of=lang_$LANG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null /bin/echo -n -e "$lt_code" |\ - dd of=lang_$LANG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null /bin/echo -n -e "$lt_resv1" |\ - dd of=lang_$LANG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null + dd of=lang_$LNG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null echo "OK" >&2 echo -n " writing offset table ($lt_offs_size bytes)..." >&2 -/bin/echo -n -e $(cat lang_$LANG.ofs | awk "$awk_ui16" | tr -d '\n'; echo) |\ - dd of=./lang_$LANG.bin bs=1 count=$lt_offs_size seek=16 conv=notrunc 2>/dev/null +/bin/echo -n -e $(cat lang_$LNG.ofs | awk "$awk_ui16" | tr -d '\n'; echo) |\ + dd of=./lang_$LNG.bin bs=1 count=$lt_offs_size seek=16 conv=notrunc 2>/dev/null echo "OK" >&2 echo -n " writing text data ($lt_data_size bytes)..." >&2 -dd if=./lang_$LANG.dat of=./lang_$LANG.bin bs=1 count=$lt_data_size seek=$((16 + $lt_offs_size)) conv=notrunc 2>/dev/null +dd if=./lang_$LNG.dat of=./lang_$LNG.bin bs=1 count=$lt_data_size seek=$((16 + $lt_offs_size)) conv=notrunc 2>/dev/null echo "OK" >&2 +#calculate and update checksum +lt_chsum=$(cat lang_$LNG.bin | xxd | cut -c11-49 | tr ' ' "\n" | sed '/^$/d' | awk 'BEGIN { sum = 0; } { sum += strtonum("0x"$1); if (sum > 0xffff) sum -= 0x10000; } END { printf("%x\n", sum); }') +/bin/echo -n -e $(echo -n $((0x$lt_chsum)) | awk "$awk_ui16") |\ + dd of=lang_$LNG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null + echo " lang_table details:" >&2 echo " lt_count = $lt_count" >&2 echo " lt_size = $lt_size" >&2 echo " lt_chsum = $lt_chsum" >&2 } -echo $LANG +echo $LNG -if [ "$LANG" = "all" ]; then +if [ "$LNG" = "all" ]; then make_lang cz make_lang de make_lang es @@ -154,7 +159,7 @@ if [ "$LANG" = "all" ]; then make_lang pl exit 0 else - make_lang $LANG + make_lang $LNG fi finish 0 diff --git a/lang/po/make_po.sh b/lang/po/make_po.sh index 881db316..315a2706 100644 --- a/lang/po/make_po.sh +++ b/lang/po/make_po.sh @@ -5,11 +5,11 @@ # SRCDIR="../../Firmware" # -LANG=$1 -if [ -z "$LANG" ]; then LANG=cz; fi +LNG=$1 +if [ -z "$LNG" ]; then LNG=cz; fi # -if [ "$LANG" == "all" ]; then +if [ "$LNG" == "all" ]; then ./make_po.sh cz ./make_po.sh de ./make_po.sh es @@ -19,13 +19,13 @@ if [ "$LANG" == "all" ]; then fi echo "make_po.sh started" >&2 -echo " selected language=$LANG" >&2 +echo " selected language=$LNG" >&2 #remove output file if exists -if [ -e lang_$LANG.po ]; then rm lang_$LANG.po; fi +if [ -e lang_$LNG.po ]; then rm lang_$LNG.po; fi lang_name=$(\ - case "$LANG" in + case "$LNG" in *en*) echo "English" ;; *cz*) echo "Czech" ;; *de*) echo "German" ;; @@ -35,7 +35,7 @@ lang_name=$(\ esac) lang_short=$(\ - case "$LANG" in + case "$LNG" in *en*) echo "en" ;; *cz*) echo "cs" ;; *de*) echo "de" ;; @@ -47,29 +47,29 @@ lang_short=$(\ po_date=$(date) #write po header -echo "# Translation of Prusa-Firmware into $lang_name." > lang_$LANG.po -echo "#" >> lang_$LANG.po -echo 'msgid ""' >> lang_$LANG.po -echo 'msgstr ""' >> lang_$LANG.po -echo '"MIME-Version: 1.0\n"' >> lang_$LANG.po -echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LANG.po -echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LANG.po -echo '"Language: '$lang_short'\n"' >> lang_$LANG.po -echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang_$LANG.po -echo '"POT-Creation-Date: '$po_date'\n"' >> lang_$LANG.po -echo '"PO-Revision-Date: '$po_date'\n"' >> lang_$LANG.po -echo '"Language-Team: \n"' >> lang_$LANG.po -echo '"X-Generator: Poedit 2.0.7\n"' >> lang_$LANG.po -echo '"X-Poedit-SourceCharset: UTF-8\n"' >> lang_$LANG.po -echo '"Last-Translator: \n"' >> lang_$LANG.po -echo '"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"' >> lang_$LANG.po -echo >> lang_$LANG.po +echo "# Translation of Prusa-Firmware into $lang_name." > lang_$LNG.po +echo "#" >> lang_$LNG.po +echo 'msgid ""' >> lang_$LNG.po +echo 'msgstr ""' >> lang_$LNG.po +echo '"MIME-Version: 1.0\n"' >> lang_$LNG.po +echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LNG.po +echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LNG.po +echo '"Language: '$lang_short'\n"' >> lang_$LNG.po +echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang_$LNG.po +echo '"POT-Creation-Date: '$po_date'\n"' >> lang_$LNG.po +echo '"PO-Revision-Date: '$po_date'\n"' >> lang_$LNG.po +echo '"Language-Team: \n"' >> lang_$LNG.po +echo '"X-Generator: Poedit 2.0.7\n"' >> lang_$LNG.po +echo '"X-Poedit-SourceCharset: UTF-8\n"' >> lang_$LNG.po +echo '"Last-Translator: \n"' >> lang_$LNG.po +echo '"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"' >> lang_$LNG.po +echo >> lang_$LNG.po #list .cpp, .c and .h files files=$(ls "$SRCDIR"/*.cpp "$SRCDIR"/*.c "$SRCDIR"/*.h) -num_texts=$(grep '^#' -c ../lang_en_$LANG.txt) -num_texts_nt=$(grep '^\"\\x00\"' -c ../lang_en_$LANG.txt) +num_texts=$(grep '^#' -c ../lang_en_$LNG.txt) +num_texts_nt=$(grep '^\"\\x00\"' -c ../lang_en_$LNG.txt) echo " $num_texts texts, $num_texts_nt not translated" >&2 #loop over all messages @@ -77,7 +77,7 @@ s0='' s1='' s2='' num=1 -cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do +cat ../lang_en_$LNG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do if [ "$s" == "" ]; then echo " processing $num of $num_texts" >&2 if [ "$s0" == "\"\\\\x00\"" ]; then @@ -103,11 +103,11 @@ cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do s2=$s1 s1=$s0 s0=$s -done >> lang_$LANG.po +done >> lang_$LNG.po #replace LF with CRLF sync -sed -i 's/$/\r/' lang_$LANG.po +sed -i 's/$/\r/' lang_$LNG.po echo "make_po.sh finished" >&2 #read diff --git a/lang/po_new/merge_lang.sh b/lang/po_new/merge_lang.sh index 0393572e..da7032c1 100644 --- a/lang/po_new/merge_lang.sh +++ b/lang/po_new/merge_lang.sh @@ -2,14 +2,14 @@ # # -LANG=$1 -if [ -z "$LANG" ]; then exit -1; fi +LNG=$1 +if [ -z "$LNG" ]; then exit -1; fi #convert '\\e' sequencies to 'x1b' and '\\' to '\' -cat $LANG.po | sed 's/\\\\e/\\x1b/g;s/\\\\/\\/g' > $LANG'_filtered.po' +cat $LNG.po | sed 's/\\\\e/\\x1b/g;s/\\\\/\\/g' > $LNG'_filtered.po' #join lines with multi-line string constants -cat $LANG'_filtered.po' | sed ':a;N;$!ba;s/\x22\n\x22//g' > $LANG'_new.po' +cat $LNG'_filtered.po' | sed ':a;N;$!ba;s/\x22\n\x22//g' > $LNG'_new.po' #generate dictionary cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do @@ -17,7 +17,7 @@ cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do if [ "${s:0:1}" = "\"" ]; then # /bin/echo -e "$s" s=$(/bin/echo -e "$s") - s2=$(grep -F -A1 -B0 "$s" "$LANG"_new.po | tail -n1 | sed 's/^msgstr //') + s2=$(grep -F -A1 -B0 "$s" "$LNG"_new.po | tail -n1 | sed 's/^msgstr //') if [ -z "$s2" ]; then echo '"\x00"' else @@ -25,4 +25,4 @@ cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do fi # echo fi -done > lang_en_$LANG.txt +done > lang_en_$LNG.txt diff --git a/lang/postbuild.sh b/lang/postbuild.sh index 8ca5b77f..6e9ff870 100644 --- a/lang/postbuild.sh +++ b/lang/postbuild.sh @@ -23,8 +23,8 @@ if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi # # Selected language: -LANG=$1 -#if [ -z "$LANG" ]; then LANG='cz'; fi +LNG=$1 +#if [ -z "$LNG" ]; then LNG='cz'; fi # # Params: IGNORE_MISSING_TEXT=1 @@ -99,8 +99,8 @@ echo "OK" >&2 #update _SEC_LANG in binary file if language is selected echo -n " secondary language data..." >&2 -if [ ! -z "$LANG" ]; then - ./update_lang.sh $LANG 2>./update_lang.out +if [ ! -z "$LNG" ]; then + ./update_lang.sh $LNG 2>./update_lang.out if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi echo "OK" >&2 finish 0 diff --git a/lang/update_lang.sh b/lang/update_lang.sh index 6acf9f8f..cc660463 100644 --- a/lang/update_lang.sh +++ b/lang/update_lang.sh @@ -9,8 +9,8 @@ if [ -z "$OBJCOPY" ]; then echo 'variable OBJCOPY not set!' >&2; exit 1; fi if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi # # Selected language: -LANG=$1 -if [ -z "$LANG" ]; then LANG='cz'; fi +LNG=$1 +if [ -z "$LNG" ]; then LNG='cz'; fi # finish() @@ -28,11 +28,11 @@ finish() } echo "update_lang.sh started" >&2 -echo " selected language=$LANG" >&2 +echo " selected language=$LNG" >&2 echo -n " checking files..." >&2 if [ ! -e text.sym ]; then echo "NG! file text.sym not found!" >&2; finish 1; fi -if [ ! -e lang_$LANG.bin ]; then echo "NG! file lang_$LANG.bin not found!" >&2; finish 1; fi +if [ ! -e lang_$LNG.bin ]; then echo "NG! file lang_$LNG.bin not found!" >&2; finish 1; fi if [ ! -e firmware.bin ]; then echo "NG! file firmware.bin not found!" >&2; finish 1; fi echo "OK" >&2 @@ -40,9 +40,15 @@ echo -n " checking symbols..." >&2 #find symbol _SEC_LANG in section '.text' sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b") if [ -z "$sec_lang" ]; then echo "NG!\n symbol _SEC_LANG not found!" >&2; finish 1; fi +#find symbol _PRI_LANG_SIGNATURE in section '.text' +pri_lang=$(cat text.sym | grep -E "\b_PRI_LANG_SIGNATURE\b") +if [ -z "$pri_lang" ]; then echo "NG!\n symbol _PRI_LANG_SIGNATURE not found!" >&2; finish 1; fi echo "OK" >&2 echo " calculating vars:" >&2 +#get pri_lang addres +pri_lang_addr='0x'$(echo $pri_lang | cut -f1 -d' ') +echo " pri_lang_addr =$pri_lang_addr" >&2 #get addres and size sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ') sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ') @@ -56,16 +62,17 @@ lang_table_size=$((256*$((($sec_lang_size - ($lang_table_addr - $sec_lang_addr)) printf " lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2 #get lang_xx.bin file size -lang_file_size=$(wc -c lang_$LANG.bin | cut -f1 -d' ') +lang_file_size=$(wc -c lang_$LNG.bin | cut -f1 -d' ') printf " lang_file_size =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2 if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi echo "updating 'firmware.bin'..." >&2 -dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null + +dd if=lang_$LNG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null #convert bin to hex echo "converting to hex..." >&2 -$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware_$LANG.hex +$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware_$LNG.hex finish 0