Merge branch 'MK3' into crash_detection_stop

This commit is contained in:
XPila 2018-06-08 18:28:43 +02:00 committed by GitHub
commit 8963757c3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 12631 additions and 2069 deletions

2
.gitignore vendored
View file

@ -4,8 +4,8 @@
Debug Debug
Firmware/Configuration_prusa.h Firmware/Configuration_prusa.h
Firmware/Doc Firmware/Doc
/Firmware/.vs/Firmware/v14
/Firmware/__vm /Firmware/__vm
/Firmware/Firmware.sln /Firmware/Firmware.sln
/Firmware/Firmware.vcxproj /Firmware/Firmware.vcxproj
/Firmware/Firmware.vcxproj.filters /Firmware/Firmware.vcxproj.filters
/Firmware/.vs/Firmware/v14

View file

@ -178,6 +178,8 @@
#define EEPROM_EXTRUDER_MULTIPLIER_0 (EEPROM_BOARD_TYPE - 4) //float #define EEPROM_EXTRUDER_MULTIPLIER_0 (EEPROM_BOARD_TYPE - 4) //float
#define EEPROM_EXTRUDER_MULTIPLIER_1 (EEPROM_EXTRUDER_MULTIPLIER_0 - 4) //float #define EEPROM_EXTRUDER_MULTIPLIER_1 (EEPROM_EXTRUDER_MULTIPLIER_0 - 4) //float
#define EEPROM_EXTRUDER_MULTIPLIER_2 (EEPROM_EXTRUDER_MULTIPLIER_1 - 4) //float #define EEPROM_EXTRUDER_MULTIPLIER_2 (EEPROM_EXTRUDER_MULTIPLIER_1 - 4) //float
#define EEPROM_EXTRUDEMULTIPLY (EEPROM_EXTRUDER_MULTIPLIER_2 - 2) // uint16
//TMC2130 configuration //TMC2130 configuration
#define EEPROM_TMC_AXIS_SIZE //axis configuration block size #define EEPROM_TMC_AXIS_SIZE //axis configuration block size

View file

@ -543,4 +543,171 @@ void LiquidCrystal_Prusa::write8bits(uint8_t value) {
} }
pulseEnable(); pulseEnable();
} }
void LiquidCrystal_Prusa::print(const char* s)
{
while (*s) write(*(s++));
}
void LiquidCrystal_Prusa::print(char c, int base)
{
print((long) c, base);
}
void LiquidCrystal_Prusa::print(unsigned char b, int base)
{
print((unsigned long) b, base);
}
void LiquidCrystal_Prusa::print(int n, int base)
{
print((long) n, base);
}
void LiquidCrystal_Prusa::print(unsigned int n, int base)
{
print((unsigned long) n, base);
}
void LiquidCrystal_Prusa::print(long n, int base)
{
if (base == 0) {
write(n);
} else if (base == 10) {
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
} else {
printNumber(n, base);
}
}
void LiquidCrystal_Prusa::print(unsigned long n, int base)
{
if (base == 0) write(n);
else printNumber(n, base);
}
void LiquidCrystal_Prusa::print(double n, int digits)
{
printFloat(n, digits);
}
void LiquidCrystal_Prusa::println(void)
{
print('\r');
print('\n');
}
/*void LiquidCrystal_Prusa::println(const String &s)
{
print(s);
println();
}*/
void LiquidCrystal_Prusa::println(const char c[])
{
print(c);
println();
}
void LiquidCrystal_Prusa::println(char c, int base)
{
print(c, base);
println();
}
void LiquidCrystal_Prusa::println(unsigned char b, int base)
{
print(b, base);
println();
}
void LiquidCrystal_Prusa::println(int n, int base)
{
print(n, base);
println();
}
void LiquidCrystal_Prusa::println(unsigned int n, int base)
{
print(n, base);
println();
}
void LiquidCrystal_Prusa::println(long n, int base)
{
print(n, base);
println();
}
void LiquidCrystal_Prusa::println(unsigned long n, int base)
{
print(n, base);
println();
}
void LiquidCrystal_Prusa::println(double n, int digits)
{
print(n, digits);
println();
}
void LiquidCrystal_Prusa::printNumber(unsigned long n, uint8_t base)
{
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
unsigned long i = 0;
if (n == 0) {
print('0');
return;
}
while (n > 0) {
buf[i++] = n % base;
n /= base;
}
for (; i > 0; i--)
print((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
}
void LiquidCrystal_Prusa::printFloat(double number, uint8_t digits)
{
// Handle negative numbers
if (number < 0.0)
{
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
print(".");
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}

View file

@ -2,7 +2,8 @@
#define LiquidCrystal_Prusa_h #define LiquidCrystal_Prusa_h
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #include <stddef.h>
//#include "Print.h"
// commands // commands
#define LCD_CLEARDISPLAY 0x01 #define LCD_CLEARDISPLAY 0x01
@ -42,7 +43,7 @@
#define LCD_5x10DOTS 0x04 #define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00 #define LCD_5x8DOTS 0x00
class LiquidCrystal_Prusa : public Print { class LiquidCrystal_Prusa/* : public Print */{
public: public:
LiquidCrystal_Prusa(uint8_t rs, uint8_t enable, LiquidCrystal_Prusa(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
@ -81,10 +82,34 @@ public:
void createChar(uint8_t, uint8_t[]); void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t, uint8_t); void setCursor(uint8_t, uint8_t);
virtual size_t write(uint8_t); // virtual size_t write(uint8_t);
size_t write(uint8_t);
void command(uint8_t); void command(uint8_t);
using Print::write; void print(const char*);
void print(char, int = 0);
void print(unsigned char, int = 0);
void print(int, int = 10);
void print(unsigned int, int = 10);
void print(long, int = 10);
void print(unsigned long, int = 10);
void print(double, int = 2);
// void println(const String &s);
void println(const char[]);
void println(char, int = 0);
void println(unsigned char, int = 0);
void println(int, int = 10);
void println(unsigned int, int = 10);
void println(long, int = 10);
void println(unsigned long, int = 10);
void println(double, int = 2);
void println(void);
void printNumber(unsigned long n, uint8_t base);
void printFloat(double number, uint8_t digits);
// using Print::write;
private: private:
void send(uint8_t, uint8_t); void send(uint8_t, uint8_t);
void write4bits(uint8_t); void write4bits(uint8_t);

View file

@ -259,11 +259,11 @@ void MarlinSerial::println(void)
print('\n'); print('\n');
} }
void MarlinSerial::println(const String &s) /*void MarlinSerial::println(const String &s)
{ {
print(s); print(s);
println(); println();
} }*/
void MarlinSerial::println(const char c[]) void MarlinSerial::println(const char c[])
{ {

View file

@ -197,12 +197,12 @@ class MarlinSerial //: public Stream
write(*buffer++); write(*buffer++);
} }
static FORCE_INLINE void print(const String &s) /* static FORCE_INLINE void print(const String &s)
{ {
for (int i = 0; i < (int)s.length(); i++) { for (int i = 0; i < (int)s.length(); i++) {
write(s[i]); write(s[i]);
} }
} }*/
static FORCE_INLINE void print(const char *str) static FORCE_INLINE void print(const char *str)
{ {

View file

@ -99,6 +99,9 @@
#include "tmc2130.h" #include "tmc2130.h"
#endif //TMC2130 #endif //TMC2130
#ifdef W25X20CL
#include "w25x20cl.h"
#endif //W25X20CL
#ifdef BLINKM #ifdef BLINKM
#include "BlinkM.h" #include "BlinkM.h"
@ -1032,6 +1035,8 @@ void __test()
while(1); while(1);
} }
#ifdef W25X20CL
void upgrade_sec_lang_from_external_flash() void upgrade_sec_lang_from_external_flash()
{ {
if ((boot_app_magic == 0x55aa55aa) && (boot_app_flags & BOOT_APP_FLG_USER0)) if ((boot_app_magic == 0x55aa55aa) && (boot_app_flags & BOOT_APP_FLG_USER0))
@ -1049,15 +1054,58 @@ void upgrade_sec_lang_from_external_flash()
boot_app_flags &= ~BOOT_APP_FLG_USER0; boot_app_flags &= ~BOOT_APP_FLG_USER0;
} }
uint8_t lang_xflash_enum_codes(uint16_t* codes)
{
lang_table_header_t header;
uint8_t count = 0;
uint32_t addr = 0x00000;
while (1)
{
printf_P(_n("LANGTABLE%d:"), count);
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t));
if (header.magic != LANG_MAGIC)
{
printf_P(_n("NG!\n"));
break;
}
printf_P(_n("OK\n"));
printf_P(_n(" _lt_magic = 0x%08lx %S\n"), header.magic, (header.magic==LANG_MAGIC)?_n("OK"):_n("NA"));
printf_P(_n(" _lt_size = 0x%04x (%d)\n"), header.size, header.size);
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\n"), header.code);
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1);
addr += header.size;
codes[count] = header.code;
count ++;
}
return count;
}
void list_sec_lang_from_external_flash()
{
uint16_t codes[8];
uint8_t count = lang_xflash_enum_codes(codes);
printf_P(_n("XFlash lang count = %hhd\n"), count);
}
#endif //W25X20CL
// "Setup" function is called by the Arduino framework on startup. // "Setup" function is called by the Arduino framework on startup.
// Before startup, the Timers-functions (PWM)/Analog RW and HardwareSerial provided by the Arduino-code // Before startup, the Timers-functions (PWM)/Analog RW and HardwareSerial provided by the Arduino-code
// are initialized by the main() routine provided by the Arduino framework. // are initialized by the main() routine provided by the Arduino framework.
void setup() void setup()
{ {
#ifdef NEW_SPI
spi_init();
#endif //NEW_SPI
lcd_init(); lcd_init();
fdev_setup_stream(lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); //setup lcdout stream fdev_setup_stream(lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); //setup lcdout stream
// upgrade_sec_lang_from_external_flash(); upgrade_sec_lang_from_external_flash();
lcd_splash(); lcd_splash();
setup_killpin(); setup_killpin();
@ -1207,9 +1255,6 @@ void setup()
#endif //TMC2130 #endif //TMC2130
#ifdef NEW_SPI
spi_init();
#endif //NEW_SPI
st_init(); // Initialize stepper, this enables interrupts! st_init(); // Initialize stepper, this enables interrupts!
@ -1353,33 +1398,36 @@ void setup()
// If they differ, an update procedure may need to be performed. At the end of this block, the current firmware version // If they differ, an update procedure may need to be performed. At the end of this block, the current firmware version
// is being written into the EEPROM, so the update procedure will be triggered only once. // is being written into the EEPROM, so the update procedure will be triggered only once.
spi_setup(TMC2130_SPCR, TMC2130_SPSR);
puts_P(_n("w25x20cl init: "));
if (w25x20cl_ini())
{
uint8_t uid[8]; // 64bit unique id
w25x20cl_rd_uid(uid);
puts_P(_n("OK, UID="));
for (uint8_t i = 0; i < 8; i ++)
printf_P(PSTR("%02hhx"), uid[i]);
putchar('\n');
list_sec_lang_from_external_flash();
}
else
puts_P(_n("NG!\n"));
lang_selected = eeprom_read_byte((uint8_t*)EEPROM_LANG); lang_selected = eeprom_read_byte((uint8_t*)EEPROM_LANG);
if (lang_selected >= LANG_NUM) if (lang_selected >= LANG_NUM)
{ {
lcd_mylang(); // lcd_mylang();
lang_selected = 0;
} }
lang_select(lang_selected); lang_select(lang_selected);
puts_P(_n("\nNew ML support")); uint16_t sec_lang_code = lang_get_code(1);
printf_P(_n(" lang_selected = %d\n"), lang_selected); printf_P(_n("SEC_LANG_CODE=0x%04x (%c%c)\n"), sec_lang_code, sec_lang_code >> 8, sec_lang_code & 0xff);
printf_P(_n(" &_SEC_LANG = 0x%04x\n"), &_SEC_LANG);
printf_P(_n(" sizeof(_SEC_LANG) = 0x%04x\n"), sizeof(_SEC_LANG));
uint16_t ptr_lang_table0 = ((uint16_t)(&_SEC_LANG) + 0xff) & 0xff00;
printf_P(_n(" &_lang_table0 = 0x%04x\n"), ptr_lang_table0);
uint32_t _lt_magic = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 0)));
uint16_t _lt_size = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 4)));
uint16_t _lt_count = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 6)));
uint16_t _lt_chsum = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 8)));
uint16_t _lt_resv0 = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 10)));
uint32_t _lt_resv1 = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 12)));
printf_P(_n(" _lt_magic = 0x%08lx %S\n"), _lt_magic, (_lt_magic==0x4bb45aa5)?_n("OK"):_n("NA"));
printf_P(_n(" _lt_size = 0x%04x (%d)\n"), _lt_size, _lt_size);
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), _lt_count, _lt_count);
printf_P(_n(" _lt_chsum = 0x%04x\n"), _lt_chsum);
printf_P(_n(" _lt_resv0 = 0x%04x\n"), _lt_resv0);
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), _lt_resv1);
puts_P(_n("\n"));
#ifdef DEBUG_SEC_LANG
lang_print_sec_lang(uartout);
#endif //DEBUG_SEC_LANG
if (eeprom_read_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE) == 255) { if (eeprom_read_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE) == 255) {
eeprom_write_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE, 0); eeprom_write_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE, 0);
@ -3320,10 +3368,10 @@ void process_commands()
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) || (echange>MIN_RETRACT && retracted)) { //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
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); retract(!retracted[active_extruder]);
return; return;
} }
@ -4456,7 +4504,7 @@ void process_commands()
KEEPALIVE_STATE(IN_HANDLER); KEEPALIVE_STATE(IN_HANDLER);
} }
if (IS_SD_PRINTING) if (IS_SD_PRINTING)
LCD_MESSAGERPGM(_i("Resuming print"));////MSG_RESUMING c=0 r=0 LCD_MESSAGERPGM(_T(MSG_RESUMING_PRINT));
else else
LCD_MESSAGERPGM(_T(WELCOME_MSG)); LCD_MESSAGERPGM(_T(WELCOME_MSG));
} }
@ -8268,6 +8316,7 @@ void uvlo_()
eeprom_update_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_2), extruder_multiplier[2]); eeprom_update_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_2), extruder_multiplier[2]);
#endif #endif
#endif #endif
eeprom_update_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY), (uint16_t)extrudemultiply);
// Finaly store the "power outage" flag. // Finaly store the "power outage" flag.
if(sd_print) eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1); if(sd_print) eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1);
@ -8483,7 +8532,7 @@ void recover_machine_state_after_power_panic()
extruder_multiplier[2] = eeprom_read_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_2)); extruder_multiplier[2] = eeprom_read_float((float*)(EEPROM_EXTRUDER_MULTIPLIER_2));
#endif #endif
#endif #endif
extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
} }
void restore_print_from_eeprom() { void restore_print_from_eeprom() {

View file

@ -25,7 +25,7 @@
#ifdef SDSUPPORT #ifdef SDSUPPORT
#include "SdBaseFile.h" #include "SdBaseFile.h"
#include <Print.h> //#include <Print.h>
#ifndef SdFile_h #ifndef SdFile_h
#define SdFile_h #define SdFile_h
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -33,7 +33,7 @@
* \class SdFile * \class SdFile
* \brief SdBaseFile with Print. * \brief SdBaseFile with Print.
*/ */
class SdFile : public SdBaseFile, public Print { class SdFile : public SdBaseFile/*, public Print*/ {
public: public:
SdFile() {} SdFile() {}
SdFile(const char* name, uint8_t oflag); SdFile(const char* name, uint8_t oflag);

View file

@ -20,10 +20,17 @@ void bootapp_print_vars()
void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size) void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size)
{ {
cli(); cli();
// uint16_t ui; for (ui = 0; ui < size; ui++)
// ram_array[ui+rptr] = 0xff;
boot_app_magic = 0x55aa55aa; boot_app_magic = 0x55aa55aa;
boot_app_flags = BOOT_APP_FLG_ERASE | BOOT_APP_FLG_COPY; boot_app_flags |= BOOT_APP_FLG_COPY;
uint16_t ui; for (ui = 0; ui < size; ui++)
{
uint8_t uc = ram_array[ui+rptr];
if (pgm_readbyte(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

@ -18,6 +18,9 @@
#define TMC2130_SPCR SPI_SPCR(TMC2130_SPI_RATE, 1, 1, 1, 0) #define TMC2130_SPCR SPI_SPCR(TMC2130_SPI_RATE, 1, 1, 1, 0)
#define TMC2130_SPSR SPI_SPSR(TMC2130_SPI_RATE) #define TMC2130_SPSR SPI_SPSR(TMC2130_SPI_RATE)
//W25X20CL configuration
#define W25X20CL_PIN_CS 32
//LANG - Multi-language support //LANG - Multi-language support
//#define LANG_MODE 0 // primary language only //#define LANG_MODE 0 // primary language only
#define LANG_MODE 1 // sec. language support #define LANG_MODE 1 // sec. language support

373
Firmware/io_atmega2560.h Normal file
View file

@ -0,0 +1,373 @@
//io_atmega2560.h
#ifndef _IO_ATMEGA2560
#define _IO_ATMEGA2560
#define __PIN_P0 PINE
#define __PIN_P1 PINE
#define __PIN_P2 PINE
#define __PIN_P3 PINE
#define __PIN_P4 PING
#define __PIN_P5 PINE
#define __PIN_P6 PINH
#define __PIN_P7 PINH
#define __PIN_P8 PINH
#define __PIN_P9 PINH
#define __PIN_P10 PINB
#define __PIN_P11 PINB
#define __PIN_P12 PINB
#define __PIN_P13 PINB
#define __PIN_P14 PINJ
#define __PIN_P15 PINJ
#define __PIN_P16 PINH
#define __PIN_P17 PINH
#define __PIN_P18 PIND
#define __PIN_P19 PIND
#define __PIN_P20 PIND
#define __PIN_P21 PIND
#define __PIN_P22 PINA
#define __PIN_P23 PINA
#define __PIN_P24 PINA
#define __PIN_P25 PINA
#define __PIN_P26 PINA
#define __PIN_P27 PINA
#define __PIN_P28 PINA
#define __PIN_P29 PINA
#define __PIN_P30 PINC
#define __PIN_P31 PINC
#define __PIN_P32 PINC
#define __PIN_P33 PINC
#define __PIN_P34 PINC
#define __PIN_P35 PINC
#define __PIN_P36 PINC
#define __PIN_P37 PINC
#define __PIN_P38 PIND
#define __PIN_P39 PING
#define __PIN_P40 PING
#define __PIN_P41 PING
#define __PIN_P42 PINL
#define __PIN_P43 PINL
#define __PIN_P44 PINL
#define __PIN_P45 PINL
#define __PIN_P46 PINL
#define __PIN_P47 PINL
#define __PIN_P48 PINL
#define __PIN_P49 PINL
#define __PIN_P50 PINB
#define __PIN_P51 PINB
#define __PIN_P52 PINB
#define __PIN_P53 PINB
#define __PIN_P54 PINF
#define __PIN_P55 PINF
#define __PIN_P56 PINF
#define __PIN_P57 PINF
#define __PIN_P58 PINF
#define __PIN_P59 PINF
#define __PIN_P60 PINF
#define __PIN_P61 PINF
#define __PIN_P62 PINK
#define __PIN_P63 PINK
#define __PIN_P64 PINK
#define __PIN_P65 PINK
#define __PIN_P66 PINK
#define __PIN_P67 PINK
#define __PIN_P68 PINK
#define __PIN_P69 PINK
#define __PIN_P70 PING
#define __PIN_P71 PING
#define __PIN_P72 PINJ
#define __PIN_P73 PINJ
#define __PIN_P74 PINJ
#define __PIN_P75 PINJ
#define __PIN_P76 PINJ
#define __PIN_P77 PINJ
#define __PIN_P78 PINE
#define __PIN_P79 PINE
#define __PIN_P80 PINE
#define __PIN_P81 PIND
#define __PIN_P82 PIND
#define __PIN_P83 PIND
#define __PIN_P84 PINH
#define __PIN_P85 PINH
#define __PORT_P0 PORTE
#define __PORT_P1 PORTE
#define __PORT_P2 PORTE
#define __PORT_P3 PORTE
#define __PORT_P4 PORTG
#define __PORT_P5 PORTE
#define __PORT_P6 PORTH
#define __PORT_P7 PORTH
#define __PORT_P8 PORTH
#define __PORT_P9 PORTH
#define __PORT_P10 PORTB
#define __PORT_P11 PORTB
#define __PORT_P12 PORTB
#define __PORT_P13 PORTB
#define __PORT_P14 PORTJ
#define __PORT_P15 PORTJ
#define __PORT_P16 PORTH
#define __PORT_P17 PORTH
#define __PORT_P18 PORTD
#define __PORT_P19 PORTD
#define __PORT_P20 PORTD
#define __PORT_P21 PORTD
#define __PORT_P22 PORTA
#define __PORT_P23 PORTA
#define __PORT_P24 PORTA
#define __PORT_P25 PORTA
#define __PORT_P26 PORTA
#define __PORT_P27 PORTA
#define __PORT_P28 PORTA
#define __PORT_P29 PORTA
#define __PORT_P30 PORTC
#define __PORT_P31 PORTC
#define __PORT_P32 PORTC
#define __PORT_P33 PORTC
#define __PORT_P34 PORTC
#define __PORT_P35 PORTC
#define __PORT_P36 PORTC
#define __PORT_P37 PORTC
#define __PORT_P38 PORTD
#define __PORT_P39 PORTG
#define __PORT_P40 PORTG
#define __PORT_P41 PORTG
#define __PORT_P42 PORTL
#define __PORT_P43 PORTL
#define __PORT_P44 PORTL
#define __PORT_P45 PORTL
#define __PORT_P46 PORTL
#define __PORT_P47 PORTL
#define __PORT_P48 PORTL
#define __PORT_P49 PORTL
#define __PORT_P50 PORTB
#define __PORT_P51 PORTB
#define __PORT_P52 PORTB
#define __PORT_P53 PORTB
#define __PORT_P54 PORTF
#define __PORT_P55 PORTF
#define __PORT_P56 PORTF
#define __PORT_P57 PORTF
#define __PORT_P58 PORTF
#define __PORT_P59 PORTF
#define __PORT_P60 PORTF
#define __PORT_P61 PORTF
#define __PORT_P62 PORTK
#define __PORT_P63 PORTK
#define __PORT_P64 PORTK
#define __PORT_P65 PORTK
#define __PORT_P66 PORTK
#define __PORT_P67 PORTK
#define __PORT_P68 PORTK
#define __PORT_P69 PORTK
#define __PORT_P70 PORTG
#define __PORT_P71 PORTG
#define __PORT_P72 PORTJ
#define __PORT_P73 PORTJ
#define __PORT_P74 PORTJ
#define __PORT_P75 PORTJ
#define __PORT_P76 PORTJ
#define __PORT_P77 PORTJ
#define __PORT_P78 PORTE
#define __PORT_P79 PORTE
#define __PORT_P80 PORTE
#define __PORT_P81 PORTD
#define __PORT_P82 PORTD
#define __PORT_P83 PORTD
#define __PORT_P84 PORTH
#define __PORT_P85 PORTH
#define __DDR_P0 DDRE
#define __DDR_P1 DDRE
#define __DDR_P2 DDRE
#define __DDR_P3 DDRE
#define __DDR_P4 DDRG
#define __DDR_P5 DDRE
#define __DDR_P6 DDRH
#define __DDR_P7 DDRH
#define __DDR_P8 DDRH
#define __DDR_P9 DDRH
#define __DDR_P10 DDRB
#define __DDR_P11 DDRB
#define __DDR_P12 DDRB
#define __DDR_P13 DDRB
#define __DDR_P14 DDRJ
#define __DDR_P15 DDRJ
#define __DDR_P16 DDRH
#define __DDR_P17 DDRH
#define __DDR_P18 DDRD
#define __DDR_P19 DDRD
#define __DDR_P20 DDRD
#define __DDR_P21 DDRD
#define __DDR_P22 DDRA
#define __DDR_P23 DDRA
#define __DDR_P24 DDRA
#define __DDR_P25 DDRA
#define __DDR_P26 DDRA
#define __DDR_P27 DDRA
#define __DDR_P28 DDRA
#define __DDR_P29 DDRA
#define __DDR_P30 DDRC
#define __DDR_P31 DDRC
#define __DDR_P32 DDRC
#define __DDR_P33 DDRC
#define __DDR_P34 DDRC
#define __DDR_P35 DDRC
#define __DDR_P36 DDRC
#define __DDR_P37 DDRC
#define __DDR_P38 DDRD
#define __DDR_P39 DDRG
#define __DDR_P40 DDRG
#define __DDR_P41 DDRG
#define __DDR_P42 DDRL
#define __DDR_P43 DDRL
#define __DDR_P44 DDRL
#define __DDR_P45 DDRL
#define __DDR_P46 DDRL
#define __DDR_P47 DDRL
#define __DDR_P48 DDRL
#define __DDR_P49 DDRL
#define __DDR_P50 DDRB
#define __DDR_P51 DDRB
#define __DDR_P52 DDRB
#define __DDR_P53 DDRB
#define __DDR_P54 DDRF
#define __DDR_P55 DDRF
#define __DDR_P56 DDRF
#define __DDR_P57 DDRF
#define __DDR_P58 DDRF
#define __DDR_P59 DDRF
#define __DDR_P60 DDRF
#define __DDR_P61 DDRF
#define __DDR_P62 DDRK
#define __DDR_P63 DDRK
#define __DDR_P64 DDRK
#define __DDR_P65 DDRK
#define __DDR_P66 DDRK
#define __DDR_P67 DDRK
#define __DDR_P68 DDRK
#define __DDR_P69 DDRK
#define __DDR_P70 DDRG
#define __DDR_P71 DDRG
#define __DDR_P72 DDRJ
#define __DDR_P73 DDRJ
#define __DDR_P74 DDRJ
#define __DDR_P75 DDRJ
#define __DDR_P76 DDRJ
#define __DDR_P77 DDRJ
#define __DDR_P78 DDRE
#define __DDR_P79 DDRE
#define __DDR_P80 DDRE
#define __DDR_P81 DDRD
#define __DDR_P82 DDRD
#define __DDR_P83 DDRD
#define __DDR_P84 DDRH
#define __DDR_P85 DDRH
#define __BIT_P0 0
#define __BIT_P1 1
#define __BIT_P2 4
#define __BIT_P3 5
#define __BIT_P4 5
#define __BIT_P5 3
#define __BIT_P6 3
#define __BIT_P7 4
#define __BIT_P8 5
#define __BIT_P9 6
#define __BIT_P10 4
#define __BIT_P11 5
#define __BIT_P12 6
#define __BIT_P13 7
#define __BIT_P14 1
#define __BIT_P15 0
#define __BIT_P16 0
#define __BIT_P17 1
#define __BIT_P18 3
#define __BIT_P19 2
#define __BIT_P20 1
#define __BIT_P21 0
#define __BIT_P22 0
#define __BIT_P23 1
#define __BIT_P24 2
#define __BIT_P25 3
#define __BIT_P26 4
#define __BIT_P27 5
#define __BIT_P28 6
#define __BIT_P29 7
#define __BIT_P30 7
#define __BIT_P31 6
#define __BIT_P32 5
#define __BIT_P33 4
#define __BIT_P34 3
#define __BIT_P35 2
#define __BIT_P36 1
#define __BIT_P37 0
#define __BIT_P38 7
#define __BIT_P39 2
#define __BIT_P40 1
#define __BIT_P41 0
#define __BIT_P42 7
#define __BIT_P43 6
#define __BIT_P44 5
#define __BIT_P45 4
#define __BIT_P46 3
#define __BIT_P47 2
#define __BIT_P48 1
#define __BIT_P49 0
#define __BIT_P50 3
#define __BIT_P51 2
#define __BIT_P52 1
#define __BIT_P53 0
#define __BIT_P54 0
#define __BIT_P55 1
#define __BIT_P56 2
#define __BIT_P57 3
#define __BIT_P58 4
#define __BIT_P59 5
#define __BIT_P60 6
#define __BIT_P61 7
#define __BIT_P62 0
#define __BIT_P63 1
#define __BIT_P64 2
#define __BIT_P65 3
#define __BIT_P66 4
#define __BIT_P67 5
#define __BIT_P68 6
#define __BIT_P69 7
#define __BIT_P70 4
#define __BIT_P71 3
#define __BIT_P72 2
#define __BIT_P73 3
#define __BIT_P74 7
#define __BIT_P75 4
#define __BIT_P76 5
#define __BIT_P77 6
#define __BIT_P78 2
#define __BIT_P79 6
#define __BIT_P80 7
#define __BIT_P81 4
#define __BIT_P82 5
#define __BIT_P83 6
#define __BIT_P84 2
#define __BIT_P85 7
#define __BIT(pin) __BIT_P##pin
#define __MSK(pin) (1 << __BIT(pin))
#define __PIN(pin) __PIN_P##pin
#define __PORT(pin) __PORT_P##pin
#define __DDR(pin) __DDR_P##pin
#define PIN(pin) __PIN(pin)
#define PORT(pin) __PORT(pin)
#define DDR(pin) __DDR(pin)
#define PIN_INP(pin) DDR(pin) &= ~__MSK(pin)
#define PIN_OUT(pin) DDR(pin) |= __MSK(pin)
#define PIN_CLR(pin) PORT(pin) &= ~__MSK(pin)
#define PIN_SET(pin) PORT(pin) |= __MSK(pin)
#define PIN_VAL(pin, val) if (val) PIN_SET(pin); else PIN_CLR(pin);
#define PIN_GET(pin) (PIN(pin) & __MSK(pin))
#endif //_IO_ATMEGA2560

View file

@ -1,55 +1,47 @@
//language.c //language.c
#include "language.h" #include "language.h"
#include <inttypes.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "bootapp.h" #include "bootapp.h"
// Currectly active language selection. #ifdef W25X20CL
unsigned char lang_selected = 0; #include "w25x20cl.h"
#endif //W25X20CL
// Currently active language selection.
uint8_t lang_selected = 0;
#if (LANG_MODE == 0) //primary language only #if (LANG_MODE == 0) //primary language only
#else //(LANG_MODE == 0)
uint8_t lang_select(uint8_t lang) { return 0; }
uint8_t lang_get_count() { return 1; }
uint16_t lang_get_code(uint8_t lang) { return LANG_CODE_EN; }
const char* lang_get_name_by_code(uint16_t code) { return _n("English"); }
#else //(LANG_MODE == 0) //secondary languages in progmem or xflash
//reserved xx kbytes for secondary language table //reserved xx kbytes for secondary language table
const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG"; const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG";
#endif //(LANG_MODE == 0)
//lang_table_t structure - 16byte header
typedef struct
{
struct
{
uint32_t magic;
uint16_t size;
uint16_t count;
uint16_t checksum;
uint16_t reserved0;
uint32_t reserved1;
} header;
uint16_t table[];
} lang_table_t;
//lang_table pointer //lang_table pointer
lang_table_t* lang_table = 0; lang_table_t* lang_table = 0;
const char* lang_get_translation(const char* s) const char* lang_get_translation(const char* s)
{ {
if (lang_selected == 0) return s + 2; //primary language selected if (lang_selected == 0) return s + 2; //primary language selected, return orig. str.
if (lang_table == 0) return s + 2; //sec. lang table not found if (lang_table == 0) return s + 2; //sec. lang table not found, return orig. str.
uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id
if (ui == 0xffff) return s + 2; //translation not found if (ui == 0xffff) return s + 2; //translation not found, return orig. str.
ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset
if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0) if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0) //read first character
return s + 2;//not translated string return s + 2;//zero length string == not translated, return orig. str.
return (const char*)((char*)lang_table + ui); //return calculated pointer return (const char*)((char*)lang_table + ui); //return calculated pointer
} }
const char* lang_get_sec_lang_str(const char* s) const char* lang_get_sec_lang_str(const char* s)
{ {
uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
ui += 0x00ff; //add 1 page
ui &= 0xff00; //align to page
lang_table_t* _lang_table = ui; //table pointer lang_table_t* _lang_table = ui; //table pointer
ui = pgm_read_word(((uint16_t*)s)); //read string id ui = pgm_read_word(((uint16_t*)s)); //read string id
if (ui == 0xffff) return s + 2; //translation not found if (ui == 0xffff) return s + 2; //translation not found
@ -57,41 +49,145 @@ const char* lang_get_sec_lang_str(const char* s)
return (const char*)((char*)_lang_table + ui); //return calculated pointer return (const char*)((char*)_lang_table + ui); //return calculated pointer
} }
const char* lang_select(unsigned char lang) uint8_t lang_select(uint8_t lang)
{ {
#if (LANG_MODE == 0) //primary language only if (lang == LANG_ID_PRI) //primary language
return 0;
#else //(LANG_MODE == 0)
if (lang == 0) //primary language
{ {
lang_table = 0; lang_table = 0;
lang_selected = 0; lang_selected = 0;
return; return 1;
} }
#ifdef W25X20CL
if (lang == LANG_ID_SEC) //current secondary language
{
uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return 0; //magic not valid
lang_table = ui; // set table pointer
lang_selected = 1; // set language id
return 1;
}
#else //W25X20CL
#endif //W25X20CL
/*
uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space
ui += 0x00ff; //add 1 page ui += 0x00ff; //add 1 page
ui &= 0xff00; //align to page ui &= 0xff00; //align to page
lang_table = ui; //set table pointer lang_table = ui; //set table pointer
ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16)))); //read relative offset of first string (language name) ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16)))); //read relative offset of first string (language name)
return (const char*)((char*)lang_table + ui); //return calculated pointer return (const char*)((char*)lang_table + ui); //return calculated pointer
*/
return 0;
}
uint8_t lang_get_count()
{
#ifdef W25X20CL
uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
uint32_t addr = 0x00000; //start of xflash
lang_table_header_t header; //table header structure
while (1)
{
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
if (header.magic != LANG_MAGIC) break; //break if magic not valid
addr += header.size; //calc address of next table
count++; //inc counter
}
return count;
#else //W25X20CL
#endif //W25X20CL
}
uint16_t lang_get_code(uint8_t lang)
{
#ifdef W25X20CL
if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN
if (lang == LANG_ID_SEC)
{
uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return LANG_CODE_XX; //magic not valid
return pgm_read_word(((uint32_t*)(ui + 10))); //return lang code from progmem
}
uint32_t addr = 0x00000; //start of xflash
lang_table_header_t header; //table header structure
lang--;
while (1)
{
w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
if (header.magic != LANG_MAGIC) break; //break if not valid
if (--lang == 0) return header.code;
addr += header.size; //calc address of next table
}
#else //W25X20CL
#endif //W25X20CL
// if (lang == LANG_ID_SEC)
// {
// uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
// if (pgm_read_dword(((uint32_t*)(ui + 0))) == LANG_MAGIC) //magic num is OK
// return pgm_read_word(((uint16_t*)(ui + 10))); //read language code
// }
return LANG_CODE_XX;
}
const char* lang_get_name_by_code(uint16_t code)
{
switch (code)
{
case LANG_CODE_EN: return _n("English");
case LANG_CODE_CZ: return _n("Cestina");
case LANG_CODE_DE: return _n("Deutsch");
case LANG_CODE_ES: return _n("Espanol");
case LANG_CODE_IT: return _n("Italiano");
case LANG_CODE_PL: return _n("Polski");
}
return _n("??");
// if (lang == LANG_ID_UNDEFINED) lang = lang_selected;
// if (lang == LANG_ID_PRI) return _T(MSG_LANGUAGE_NAME + 2);
// if (lang == LANG_ID_SEC)
// {
// uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
// if (pgm_read_dword(((uint32_t*)(ui + 0))) == LANG_MAGIC) //magic num is OK
// return lang_get_sec_lang_str(MSG_LANGUAGE_NAME);
// }
// return 0;
}
#ifdef DEBUG_SEC_LANG
const char* lang_get_sec_lang_str_by_id(uint16_t id)
{
uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
return ui + pgm_read_word(((uint16_t*)(ui + 16 + id * 2))); //read relative offset and return calculated pointer
}
uint16_t lang_print_sec_lang(FILE* out)
{
printf_P(_n("&_SEC_LANG = 0x%04x\n"), &_SEC_LANG);
printf_P(_n("sizeof(_SEC_LANG) = 0x%04x\n"), sizeof(_SEC_LANG));
uint16_t ptr_lang_table0 = ((uint16_t)(&_SEC_LANG) + 0xff) & 0xff00;
printf_P(_n("&_lang_table0 = 0x%04x\n"), ptr_lang_table0);
uint32_t _lt_magic = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 0)));
uint16_t _lt_size = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 4)));
uint16_t _lt_count = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 6)));
uint16_t _lt_chsum = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 8)));
uint16_t _lt_resv0 = pgm_read_word(((uint16_t*)(ptr_lang_table0 + 10)));
uint32_t _lt_resv1 = pgm_read_dword(((uint32_t*)(ptr_lang_table0 + 12)));
printf_P(_n(" _lt_magic = 0x%08lx %S\n"), _lt_magic, (_lt_magic==LANG_MAGIC)?_n("OK"):_n("NA"));
printf_P(_n(" _lt_size = 0x%04x (%d)\n"), _lt_size, _lt_size);
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), _lt_count, _lt_count);
printf_P(_n(" _lt_chsum = 0x%04x\n"), _lt_chsum);
printf_P(_n(" _lt_resv0 = 0x%04x\n"), _lt_resv0);
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), _lt_resv1);
if (_lt_magic != LANG_MAGIC) return 0;
puts_P(_n(" strings:\n"));
uint16_t ui = ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00); //table pointer
for (ui = 0; ui < _lt_count; ui++)
fprintf_P(out, _n(" %3d %S\n"), ui, lang_get_sec_lang_str_by_id(ui));
return _lt_count;
}
#endif //DEBUG_SEC_LANG
#endif //(LANG_MODE == 0) #endif //(LANG_MODE == 0)
}
unsigned char lang_get_count() //const char MSG_LANGUAGE_NAME[] PROGMEM_I1 = ISTR("English"); ////c=0 r=0
{
uint16_t ui = (uint16_t)&_SEC_LANG; //pointer to _SEC_LANG reserved space
ui += 0x00ff; //add 1 page
ui &= 0xff00; //align to page
lang_table_t* _lang_table = ui; //table pointer
if (pgm_read_dword(((uint32_t*)(_lang_table + 0))) == 0x4bb45aa5) return 2;
return 1;
}
const char* lang_get_name(unsigned char lang)
{
if (lang == 0) return MSG_LANGUAGE_NAME + 2;
return lang_get_sec_lang_str(MSG_LANGUAGE_NAME);
}
const char MSG_LANGUAGE_NAME[] PROGMEM_I1 = ISTR("English"); ////c=0 r=0

View file

@ -2,13 +2,15 @@
#ifndef LANGUAGE_H #ifndef LANGUAGE_H
#define LANGUAGE_H #define LANGUAGE_H
#define W25X20CL
#include "config.h" #include "config.h"
#include <inttypes.h>
//#include <stdio.h>
#define PROTOCOL_VERSION "1.0" #define PROTOCOL_VERSION "1.0"
#ifdef CUSTOM_MENDEL_NAME #ifndef CUSTOM_MENDEL_NAME
// #define CUSTOM_MENDEL_NAME CUSTOM_MENDEL_NAME
#else
#define MACHINE_NAME "Mendel" #define MACHINE_NAME "Mendel"
#endif #endif
@ -42,6 +44,23 @@
#define _N(s) (__extension__({static const char __c[] PROGMEM_N1 = s; &__c[0];})) #define _N(s) (__extension__({static const char __c[] PROGMEM_N1 = s; &__c[0];}))
#define _n(s) _N(s) #define _n(s) _N(s)
//lang_table_header_t structure - (size= 16byte)
typedef struct
{
uint32_t magic; //+0
uint16_t size; //+4
uint16_t count; //+6
uint16_t checksum; //+8
uint16_t code; //+10
uint32_t reserved1; //+12
} lang_table_header_t;
//lang_table_t structure - (size= 16byte + 2*count)
typedef struct
{
lang_table_header_t header;
uint16_t table[];
} lang_table_t;
// Language indices into their particular symbol tables. // Language indices into their particular symbol tables.
#define LANG_ID_PRI 0 #define LANG_ID_PRI 0
@ -49,6 +68,7 @@
// Language is not defined and it shall be selected from the menu. // Language is not defined and it shall be selected from the menu.
#define LANG_ID_FORCE_SELECTION 254 #define LANG_ID_FORCE_SELECTION 254
// Language is not defined on a virgin RAMBo board. // Language is not defined on a virgin RAMBo board.
#define LANG_ID_UNDEFINED 255 #define LANG_ID_UNDEFINED 255
@ -58,24 +78,43 @@
// Number of languages available in the language table. // Number of languages available in the language table.
#define LANG_NUM 2 #define LANG_NUM 2
// Magic number at begin of lang table.
#define LANG_MAGIC 0x4bb45aa5
// Language codes (ISO639-1)
#define LANG_CODE_XX 0x3f3f //'??'
#define LANG_CODE_EN 0x656e //'en'
#define LANG_CODE_CZ 0x6373 //'cs'
#define LANG_CODE_DE 0x6465 //'de'
#define LANG_CODE_ES 0x6573 //'es'
#define LANG_CODE_IT 0x6974 //'it'
#define LANG_CODE_PL 0x706c //'pl'
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif //defined(__cplusplus) #endif //defined(__cplusplus)
// Currectly active language selection. // Currectly active language selection.
extern unsigned char lang_selected; extern uint8_t lang_selected;
#if (LANG_MODE != 0) #if (LANG_MODE != 0)
extern const char _SEC_LANG[LANG_SIZE_RESERVED]; extern const char _SEC_LANG[LANG_SIZE_RESERVED];
#endif //(LANG_MODE == 0)
extern const char* lang_get_translation(const char* s); extern const char* lang_get_translation(const char* s);
extern const char* lang_get_sec_lang_str(const char* s); extern const char* lang_get_sec_lang_str(const char* s);
extern const char* lang_select(unsigned char lang); #endif //(LANG_MODE != 0)
extern unsigned char lang_get_count();
extern const char* lang_get_name(unsigned char lang);
//selects
extern uint8_t lang_select(uint8_t lang);
//get total number of languages (primary + all in xflash)
extern uint8_t lang_get_count();
extern uint16_t lang_get_code(uint8_t lang);
extern const char* lang_get_name_by_code(uint16_t code);
#ifdef DEBUG_SEC_LANG
extern const char* lang_get_sec_lang_str_by_id(uint16_t id);
extern uint16_t lang_print_sec_lang(FILE* out);
#endif //DEBUG_SEC_LANG
#if defined(__cplusplus) #if defined(__cplusplus)
} }
@ -84,7 +123,8 @@ extern const char* lang_get_name(unsigned char lang);
#define CAT2(_s1, _s2) _s1 #define CAT2(_s1, _s2) _s1
#define CAT4(_s1, _s2, _s3, _s4) _s1 #define CAT4(_s1, _s2, _s3, _s4) _s1
extern const char MSG_LANGUAGE_NAME[]; //Localized language name
//extern const char MSG_LANGUAGE_NAME[];
#include "messages.h" #include "messages.h"

View file

@ -2479,7 +2479,7 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8
// Print the decrasing ID of the measurement point. // Print the decrasing ID of the measurement point.
#ifdef MESH_BED_CALIBRATION_SHOW_LCD #ifdef MESH_BED_CALIBRATION_SHOW_LCD
lcd_implementation_print_at(0, next_line, mesh_point+1); lcd_implementation_print_at(0, next_line, mesh_point+1);
lcd_printPGM(_i(" of 4"));////MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0 lcd_printPGM(_T(MSG_FIND_BED_OFFSET_AND_SKEW_LINE2));////MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
#endif /* MESH_BED_CALIBRATION_SHOW_LCD */ #endif /* MESH_BED_CALIBRATION_SHOW_LCD */
// Move up. // Move up.

View file

@ -71,6 +71,7 @@ const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20 r=0
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"); ////c=0 r=0 const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\xF8" "Refresh"); ////c=0 r=0
const char MSG_RESUMING_PRINT[] PROGMEM_I1 = ISTR("Resuming print"); ////c=0 r=0
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_SD_ERR_WRITE_TO_FILE[] PROGMEM_I1 = ISTR("error writing to file"); ////c=0 r=0 const char MSG_SD_ERR_WRITE_TO_FILE[] PROGMEM_I1 = ISTR("error writing to file"); ////c=0 r=0
const char MSG_SD_OPEN_FILE_FAIL[] PROGMEM_I1 = ISTR("open failed, File: "); ////c=0 r=0 const char MSG_SD_OPEN_FILE_FAIL[] PROGMEM_I1 = ISTR("open failed, File: "); ////c=0 r=0

View file

@ -69,6 +69,7 @@ extern const char MSG_PULL_OUT_FILAMENT[];
extern const char MSG_RECOVER_PRINT[]; extern const char MSG_RECOVER_PRINT[];
extern const char MSG_REFRESH[]; extern const char MSG_REFRESH[];
extern const char MSG_REMOVE_STEEL_SHEET[]; extern const char MSG_REMOVE_STEEL_SHEET[];
extern const char MSG_RESUMING_PRINT[];
extern const char MSG_SD_ERR_WRITE_TO_FILE[]; extern const char MSG_SD_ERR_WRITE_TO_FILE[];
extern const char MSG_SD_OPEN_FILE_FAIL[]; extern const char MSG_SD_OPEN_FILE_FAIL[];
extern const char MSG_SD_WORKDIR_FAIL[]; extern const char MSG_SD_WORKDIR_FAIL[];

View file

@ -15,6 +15,7 @@
#define AMBIENT_THERMISTOR #define AMBIENT_THERMISTOR
#define PINDA_THERMISTOR #define PINDA_THERMISTOR
#define W25X20CL // external 256kB flash
#define SWI2C // enable software i2c #define SWI2C // enable software i2c
#define SWI2C_A8 // 8bit address functions #define SWI2C_A8 // 8bit address functions

View file

@ -15,7 +15,11 @@
#define DD_MOSI 2 #define DD_MOSI 2
#define DD_MISO 3 #define DD_MISO 3
inline void spi_init() #if defined(__cplusplus)
extern "C" {
#endif //defined(__cplusplus)
static inline void spi_init()
{ {
DDRB &= ~((1 << DD_SCK) | (1 << DD_MOSI) | (1 << DD_MISO)); DDRB &= ~((1 << DD_SCK) | (1 << DD_MOSI) | (1 << DD_MISO));
DDRB |= (1 << DD_SS) | (1 << DD_SCK) | (1 << DD_MOSI); DDRB |= (1 << DD_SS) | (1 << DD_SCK) | (1 << DD_MOSI);
@ -25,17 +29,21 @@ inline void spi_init()
SPSR = 0x00; SPSR = 0x00;
} }
inline void spi_setup(uint8_t spcr, uint8_t spsr) static inline void spi_setup(uint8_t spcr, uint8_t spsr)
{ {
SPCR = spcr; SPCR = spcr;
SPSR = spsr; SPSR = spsr;
} }
inline uint8_t spi_txrx(uint8_t tx) static inline uint8_t spi_txrx(uint8_t tx)
{ {
SPDR = tx; SPDR = tx;
while (!(SPSR & (1 << SPIF))); while (!(SPSR & (1 << SPIF)));
return SPDR; return SPDR;
} }
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)
#endif //SPI_H #endif //SPI_H

View file

@ -702,7 +702,7 @@ void lcd_commands()
strcat(cmd1, ftostr32(pause_lastpos[Y_AXIS])); strcat(cmd1, ftostr32(pause_lastpos[Y_AXIS]));
enquecommand(cmd1); enquecommand(cmd1);
lcd_setstatuspgm(_i("Resuming print"));////MSG_RESUMING_PRINT c=20 r=1 lcd_setstatuspgm(_T(MSG_RESUMING_PRINT));
lcd_commands_step = 3; lcd_commands_step = 3;
} }
} }
@ -1721,9 +1721,9 @@ static void lcd_menu_temperatures()
static void lcd_menu_voltages() static void lcd_menu_voltages()
{ {
float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC; float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
//float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC; // float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
//fprintf_P(lcdout, PSTR(ESC_H(1,1) "PWR: %d.%01dV" ESC_H(1,2) "BED: %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr)), (int)volt_bed, (int)(10*fabs(volt_bed - (int)volt_bed))); // fprintf_P(lcdout, PSTR(ESC_H(1,1)"PWR: %d.%01dV" ESC_H(1,2)"BED: %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr)), (int)volt_bed, (int)(10*fabs(volt_bed - (int)volt_bed)));
fprintf_P(lcdout, PSTR( ESC_H(1,1) "PWR: %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ; fprintf_P(lcdout, PSTR( ESC_H(1,1)"PWR: %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ;
if (lcd_clicked()) if (lcd_clicked())
{ {
menu_action_back(); menu_action_back();
@ -3714,14 +3714,25 @@ static void lcd_crash_mode_set()
#endif //TMC2130 #endif //TMC2130
static void lcd_set_lang(unsigned char lang) { static void lcd_set_lang(unsigned char lang)
lang_selected = lang; {
firstrun = 1; if (lang > LANG_ID_SEC)
eeprom_update_byte((unsigned char *)EEPROM_LANG, lang); if (!lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Copy selected language from XFLASH?"), false, true))
/*langsel=0;*/ {
if (langsel == LANGSEL_MODAL) lcd_return_to_status();
// From modal mode to an active mode? This forces the menu to return to the setup menu. lcd_update_enable(true);
langsel = LANGSEL_ACTIVE; return;
}
lang_select(lang);
/*
lang_selected = lang;
firstrun = 1;
eeprom_update_byte((unsigned char *)EEPROM_LANG, lang);
// langsel=0;
if (langsel == LANGSEL_MODAL)
// From modal mode to an active mode? This forces the menu to return to the setup menu.
langsel = LANGSEL_ACTIVE;
*/
} }
#ifdef PAT9125 #ifdef PAT9125
@ -3755,17 +3766,22 @@ void lcd_force_language_selection() {
eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION); eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
} }
#if (LANG_MODE != 0)
static void lcd_language_menu() static void lcd_language_menu()
{ {
START_MENU(); START_MENU();
if (langsel == LANGSEL_OFF) if (langsel == LANGSEL_OFF)
MENU_ITEM(back, _T(MSG_SETTINGS), 0); MENU_ITEM(back, _T(MSG_SETTINGS), 0);
else if (langsel == LANGSEL_ACTIVE) else if (langsel == LANGSEL_ACTIVE)
MENU_ITEM(back, _T(MSG_WATCH), 0); MENU_ITEM(back, _T(MSG_WATCH), 0);
for (int i=0; i < lang_get_count(); i++) MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0);
MENU_ITEM(setlang, lang_get_name(i), i); // MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1);
END_MENU(); for (int i = 2; i < lang_get_count(); i++) //skip seconday language - solved in menu_action_setlang
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i);
END_MENU();
} }
#endif //(LANG_MODE != 0)
void lcd_mesh_bedleveling() void lcd_mesh_bedleveling()
{ {
@ -4231,7 +4247,10 @@ static void lcd_settings_menu()
{ {
MENU_ITEM(submenu, _T(MSG_BABYSTEP_Z), lcd_babystep_z); MENU_ITEM(submenu, _T(MSG_BABYSTEP_Z), lcd_babystep_z);
} }
#if (LANG_MODE != 0)
MENU_ITEM(submenu, _i("Select language"), lcd_language_menu);////MSG_LANGUAGE_SELECT c=0 r=0 MENU_ITEM(submenu, _i("Select language"), lcd_language_menu);////MSG_LANGUAGE_SELECT c=0 r=0
#endif //(LANG_MODE != 0)
if (card.ToshibaFlashAir_isEnabled()) { if (card.ToshibaFlashAir_isEnabled()) {
MENU_ITEM(function, _i("SD card [FlshAir]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1 MENU_ITEM(function, _i("SD card [FlshAir]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
@ -4590,7 +4609,7 @@ void lcd_mylang_drawmenu(int cursor) {
} }
} }
*/ */
/*
void lcd_mylang_drawmenu(int cursor) void lcd_mylang_drawmenu(int cursor)
{ {
unsigned char lang_cnt = lang_get_count(); unsigned char lang_cnt = lang_get_count();
@ -4641,7 +4660,8 @@ void lcd_mylang_drawmenu(int cursor)
lcd.print("^"); lcd.print("^");
} }
} }
*/
/*
void lcd_mylang_drawcursor(int cursor) { void lcd_mylang_drawcursor(int cursor) {
unsigned char lang_cnt = lang_get_count(); unsigned char lang_cnt = lang_get_count();
@ -4651,8 +4671,9 @@ void lcd_mylang_drawcursor(int cursor) {
lcd.print(">"); lcd.print(">");
} }
*/
/*
void lcd_mylang() void lcd_mylang()
{ {
int enc_dif = 0; int enc_dif = 0;
@ -4709,15 +4730,13 @@ void lcd_mylang()
delay(500); delay(500);
} }
/* // if (++counter == 80) {
if (++counter == 80) { // hlaska++;
hlaska++; // if(hlaska>LANG_NUM) hlaska=1;
if(hlaska>LANG_NUM) hlaska=1; // lcd_mylang_top(hlaska);
lcd_mylang_top(hlaska); // lcd_mylang_drawcursor(cursor_pos);
lcd_mylang_drawcursor(cursor_pos); // counter=0;
counter=0; // }
}
*/
}; };
if(MYSERIAL.available() > 1){ if(MYSERIAL.available() > 1){
@ -4730,7 +4749,7 @@ void lcd_mylang()
lcd_return_to_status(); lcd_return_to_status();
} }
*/
void bowden_menu() { void bowden_menu() {
int enc_dif = encoderDiff; int enc_dif = encoderDiff;
int cursor_pos = 0; int cursor_pos = 0;
@ -5638,6 +5657,13 @@ void lcd_confirm_print()
} }
extern void __test();
static void lcd_test_menu()
{
__test();
}
static void lcd_main_menu() static void lcd_main_menu()
{ {
@ -5807,6 +5833,7 @@ static void lcd_main_menu()
#endif #endif
MENU_ITEM(submenu, _i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0 MENU_ITEM(submenu, _i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0
// MENU_ITEM(submenu, _i("Test"), lcd_test_menu);////MSG_SUPPORT c=0 r=0
END_MENU(); END_MENU();
@ -7315,9 +7342,23 @@ static void menu_action_submenu(menuFunc_t data) {
static void menu_action_gcode(const char* pgcode) { static void menu_action_gcode(const char* pgcode) {
enquecommand_P(pgcode); enquecommand_P(pgcode);
} }
static void menu_action_setlang(unsigned char lang) {
lcd_set_lang(lang); static void menu_action_setlang(unsigned char lang)
{
if (lang <= LANG_ID_SEC)
{
lcd_set_lang(lang);
return;
}
uint16_t code = lang_get_code(lang);
if (code == lang_get_code(1))
{
lcd_set_lang(1);
return;
}
lcd_set_lang(lang);
} }
static void menu_action_function(menuFunc_t data) { static void menu_action_function(menuFunc_t data) {
(*data)(); (*data)();
} }

View file

@ -32,7 +32,7 @@
void prusa_statistics(int _message, uint8_t _col_nr = 0); void prusa_statistics(int _message, uint8_t _col_nr = 0);
void lcd_confirm_print(); void lcd_confirm_print();
unsigned char lcd_choose_color(); unsigned char lcd_choose_color();
void lcd_mylang(); //void lcd_mylang();
bool lcd_detected(void); bool lcd_detected(void);
static void lcd_selftest_v(); static void lcd_selftest_v();

View file

@ -973,7 +973,7 @@ if (print_sd_status)
lcd.setCursor(0, 3); lcd.setCursor(0, 3);
lcd_printPGM(PSTR(" ")); lcd_printPGM(PSTR(" "));
lcd.setCursor(0, 3); lcd.setCursor(0, 3);
lcd_printPGM(_i("Calibrating Z"));////MSG_HOMEYZ_PROGRESS c=0 r=0 lcd_printPGM(_T(MSG_CALIBRATE_Z_AUTO));
lcd_printPGM(PSTR(" : ")); lcd_printPGM(PSTR(" : "));
lcd.print(custom_message_state-10); lcd.print(custom_message_state-10);
} }

View file

@ -149,6 +149,7 @@
#define MINTEMP_MINAMBIENT_RAW 978 #define MINTEMP_MINAMBIENT_RAW 978
//#define DEBUG_BUILD //#define DEBUG_BUILD
//#define DEBUG_SEC_LANG //secondary language debug output at startup
#ifdef DEBUG_BUILD #ifdef DEBUG_BUILD
//#define _NO_ASM //#define _NO_ASM
#define DEBUG_DCODES //D codes #define DEBUG_DCODES //D codes

178
Firmware/w25x20cl.c Normal file
View file

@ -0,0 +1,178 @@
//w25x20cl.c
#include "w25x20cl.h"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "io_atmega2560.h"
#include "spi.h"
#define _MFRID 0xEF
#define _DEVID 0x11
#define _CMD_ENABLE_WR 0x06
#define _CMD_ENABLE_WR_VSR 0x50
#define _CMD_DISABLE_WR 0x04
#define _CMD_RD_STATUS_REG 0x05
#define _CMD_WR_STATUS_REG 0x01
#define _CMD_RD_DATA 0x03
#define _CMD_RD_FAST 0x0b
#define _CMD_RD_FAST_D_O 0x3b
#define _CMD_RD_FAST_D_IO 0xbb
#define _CMD_PAGE_PROGRAM 0x02
#define _CMD_SECTOR_ERASE 0x20
#define _CMD_BLOCK32_ERASE 0x52
#define _CMD_BLOCK64_ERASE 0xd8
#define _CMD_CHIP_ERASE 0xc7
#define _CMD_CHIP_ERASE2 0x60
#define _CMD_PWR_DOWN 0xb9
#define _CMD_PWR_DOWN_REL 0xab
#define _CMD_MFRID_DEVID 0x90
#define _CMD_MFRID_DEVID_D 0x92
#define _CMD_JEDEC_ID 0x9f
#define _CMD_RD_UID 0x4b
#define _CS_LOW() PORT(W25X20CL_PIN_CS) &= ~__MSK(W25X20CL_PIN_CS)
#define _CS_HIGH() PORT(W25X20CL_PIN_CS) |= __MSK(W25X20CL_PIN_CS)
//#define _SPI_TX swspi_tx
//#define _SPI_RX swspi_rx
#define _SPI_TX(b) spi_txrx(b)
#define _SPI_RX() spi_txrx(0xff)
int w25x20cl_mfrid_devid(void);
int8_t w25x20cl_ini(void)
{
PIN_OUT(W25X20CL_PIN_CS);
_CS_HIGH();
if (!w25x20cl_mfrid_devid()) return 0;
return 1;
}
void w25x20cl_enable_wr(void)
{
_CS_LOW();
_SPI_TX(_CMD_ENABLE_WR); // send command 0x06
_CS_HIGH();
}
void w25x20cl_disable_wr(void)
{
_CS_LOW();
_SPI_TX(_CMD_DISABLE_WR); // send command 0x04
_CS_HIGH();
}
uint8_t w25x20cl_rd_status_reg(void)
{
_CS_LOW();
_SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90
uint8_t val = _SPI_RX(); // receive value
_CS_HIGH();
return val;
}
void w25x20cl_wr_status_reg(uint8_t val)
{
_CS_LOW();
_SPI_TX(_CMD_WR_STATUS_REG); // send command 0x90
_SPI_TX(val); // send value
_CS_HIGH();
}
void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt)
{
_CS_LOW();
_SPI_TX(_CMD_RD_DATA); // send command 0x03
_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
while (cnt--) // receive data
*(data++) = _SPI_RX();
_CS_HIGH();
}
void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt)
{
_CS_LOW();
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
_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
while (cnt--) // send data
_SPI_TX(*(data++));
_CS_HIGH();
}
void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt)
{
_CS_LOW();
_SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02
_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
while (cnt--) // send data
_SPI_TX(pgm_read_byte(data++));
_CS_HIGH();
}
void w25x20cl_erase(uint8_t cmd, uint32_t addr)
{
_CS_LOW();
_SPI_TX(_CMD_SECTOR_ERASE); // 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
_CS_HIGH();
}
void w25x20cl_sector_erase(uint32_t addr)
{
return w25x20cl_erase(_CMD_SECTOR_ERASE, addr);
}
void w25x20cl_block32_erase(uint32_t addr)
{
return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr);
}
void w25x20cl_block64_erase(uint32_t addr)
{
return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr);
}
void w25x20cl_chip_erase(void)
{
_CS_LOW();
_SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7
_CS_HIGH();
}
void w25x20cl_rd_uid(uint8_t* uid)
{
_CS_LOW();
_SPI_TX(_CMD_RD_UID); // send command 0x4b
uint8_t cnt = 4; // 4 dummy bytes
while (cnt--) // receive dummy bytes
_SPI_RX();
cnt = 8; // 8 bytes UID
while (cnt--) // receive UID
uid[7 - cnt] = _SPI_RX();
_CS_HIGH();
}
int w25x20cl_mfrid_devid(void)
{
_CS_LOW();
_SPI_TX(_CMD_MFRID_DEVID); // send command 0x90
uint8_t cnt = 3; // 3 address bytes
while (cnt--) // send address bytes
_SPI_TX(0x00);
uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid
uint8_t w25x20cl_devid = _SPI_RX(); // receive devid
_CS_HIGH();
return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID));
}

40
Firmware/w25x20cl.h Normal file
View file

@ -0,0 +1,40 @@
//w25x20cl.h
#ifndef _W25X20CL_H
#define _W25X20CL_H
#include <inttypes.h>
#include "config.h"
#define W25_STATUS_BUSY 0x01
#define W25_STATUS_WEL 0x02
#define W25_STATUS_BP0 0x04
#define W25_STATUS_BP1 0x08
#define W25_STATUS_TB 0x20
#define W25_STATUS_SRP 0x80
#if defined(__cplusplus)
extern "C" {
#endif //defined(__cplusplus)
extern int8_t w25x20cl_ini(void);
extern void w25x20cl_enable_wr(void);
extern void w25x20cl_disable_wr(void);
extern uint8_t w25x20cl_rd_status_reg(void);
extern void w25x20cl_wr_status_reg(uint8_t val);
extern void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt);
extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt);
extern void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt);
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_rd_uid(uint8_t* uid);
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)
#endif //_W25X20CL_H

View file

@ -1,4 +1,4 @@
# 1. Developement environment preparing # 1. Development environment preparation
1. install `"Arduino Software IDE"` for your preferred operating system 1. install `"Arduino Software IDE"` for your preferred operating system
`https://www.arduino.cc -> Software->Downloads` `https://www.arduino.cc -> Software->Downloads`

64
lang/config.sh Normal file
View file

@ -0,0 +1,64 @@
#!/bin/sh
#
# config.sh - multi-language support configuration script
# Definition of absolute paths etc.
# This file is 'included' in all scripts.
#
# Arduino main folder:
export ARDUINO=C:/arduino-1.6.8
#
# Arduino builder:
export BUILDER=$ARDUINO/arduino_debug.exe
#
# AVR gcc tools:
export OBJCOPY=$ARDUINO/hardware/tools/avr/bin/avr-objcopy.exe
export OBJDUMP=$ARDUINO/hardware/tools/avr/bin/avr-objdump.exe
#
# Output folder:
export OUTDIR="../../output"
#
# Objects folder:
export OBJDIR="$OUTDIR/sketch"
#
# Generated elf file:
export INOELF="$OUTDIR/Firmware.ino.elf"
#
# Generated hex file:
export INOHEX="$OUTDIR/Firmware.ino.hex"
echo "config.sh started" >&2
_err=0
echo -n " Arduino main folder: " >&2
if [ -e $ARDUINO ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=1; fi
echo -n " Arduino builder: " >&2
if [ -e $BUILDER ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=2; fi
echo " AVR gcc tools:" >&2
echo -n " objcopy " >&2
if [ -e $OBJCOPY ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=3; fi
echo -n " objdump " >&2
if [ -e $OBJDUMP ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=4; fi
echo -n " Output folder: " >&2
if [ -e $OUTDIR ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=5; fi
echo -n " Objects folder: " >&2
if [ -e $OBJDIR ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=6; fi
echo -n " Generated elf file: " >&2
if [ -e $INOELF ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=7; fi
echo -n " Generated hex file: " >&2
if [ -e $INOHEX ]; then echo 'OK' >&2; else echo 'NG!' >&2; _err=8; fi
if [ $_err -eq 0 ]; then
echo "config.sh finished with success" >&2
export CONFIG_OK=1
else
echo "config.sh finished with errors!" >&2
export CONFIG_OK=0
fi

View file

@ -22,9 +22,6 @@
#MSG_CONFIGURATION_VER c=0 r=0 #MSG_CONFIGURATION_VER c=0 r=0
" Last Updated: " " Last Updated: "
#MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0 #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4" " of 4"
@ -139,9 +136,6 @@
#MSG_CALIBRATE_Z_AUTO c=20 r=2 #MSG_CALIBRATE_Z_AUTO c=20 r=2
"Calibrating Z" "Calibrating Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z"
#MSG_MOVE_CARRIAGE_TO_THE_TOP_Z c=20 r=8 #MSG_MOVE_CARRIAGE_TO_THE_TOP_Z c=20 r=8
"Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
@ -253,9 +247,6 @@
#MSG_INFO_EXTRUDER c=15 r=1 #MSG_INFO_EXTRUDER c=15 r=1
"Extruder info" "Extruder info"
#MSG_EXTRUDER c=17 r=1
"Extruder"
#MSG_MOVE_E c=0 r=0 #MSG_MOVE_E c=0 r=0
"Extruder" "Extruder"
@ -751,9 +742,6 @@
#MSG_RESUME_PRINT c=0 r=0 #MSG_RESUME_PRINT c=0 r=0
"Resume print" "Resume print"
#MSG_RESUMING c=0 r=0
"Resuming print"
#MSG_RESUMING_PRINT c=20 r=1 #MSG_RESUMING_PRINT c=20 r=1
"Resuming print" "Resuming print"

View file

@ -34,10 +34,6 @@
" of 4" " of 4"
" z 4" " z 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
" z 4"
#MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0
" of 9" " of 9"
" z 9" " z 9"
@ -182,11 +178,7 @@
"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
"Kalibrace XYZ. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem." "Kalibrace XYZ. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem."
#MSG_HOMEYZ_PROGRESS c=0 r=0 #MSG_CALIBRATE_Z_AUTO c=0 r=0
"Calibrating Z"
"Kalibruji Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z" "Calibrating Z"
"Kalibruji Z" "Kalibruji Z"
@ -342,10 +334,6 @@
"Extruder" "Extruder"
"Extruder" "Extruder"
#MSG_MOVE_E c=0 r=0
"Extruder"
"Extruder"
#MSG_FSENS_AUTOLOAD_ON c=17 r=1 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
"F. autoload [on]" "F. autoload [on]"
"F. autozav. [zap]" "F. autozav. [zap]"
@ -1002,11 +990,7 @@
"Resume print" "Resume print"
"Pokracovat" "Pokracovat"
#MSG_RESUMING c=0 r=0 #MSG_RESUMING_PRINT c=0 r=0
"Resuming print"
"Obnoveni tisku"
#MSG_RESUMING c=0 r=0
"Resuming print" "Resuming print"
"Obnoveni tisku" "Obnoveni tisku"

View file

@ -34,10 +34,6 @@
" of 4" " of 4"
" von 4" " von 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
" von 4"
#MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0
" of 9" " of 9"
" von 9" " von 9"
@ -182,11 +178,7 @@
"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
"Kalibrieren von XYZ. Drehen Sie den Knopf bis der obere Anschlag erreicht wird. Klicken Sie den Knopf wenn es ganz oben wird." "Kalibrieren von XYZ. Drehen Sie den Knopf bis der obere Anschlag erreicht wird. Klicken Sie den Knopf wenn es ganz oben wird."
#MSG_HOMEYZ_PROGRESS c=0 r=0 #MSG_CALIBRATE_Z_AUTO c=0 r=0
"Calibrating Z"
"Kalibriere Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z" "Calibrating Z"
"Kalibriere Z" "Kalibriere Z"
@ -296,7 +288,7 @@
#MSG_Enqueing c=0 r=0 #MSG_Enqueing c=0 r=0
"enqueing \x22" "enqueing \x22"
"enqueuing \x22 "enqueuing \x22"
#MSG_STACK_ERROR c=20 r=4 #MSG_STACK_ERROR c=20 r=4
"Error - static memory has been overwritten" "Error - static memory has been overwritten"
@ -342,10 +334,6 @@
"Extruder" "Extruder"
"Extruder" "Extruder"
#MSG_MOVE_E c=0 r=0
"Extruder"
"Extruder"
#MSG_FSENS_AUTOLOAD_ON c=17 r=1 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
"F. autoload [on]" "F. autoload [on]"
"\x00" "\x00"
@ -1002,11 +990,7 @@
"Resume print" "Resume print"
"Fortsetzen" "Fortsetzen"
#MSG_RESUMING c=0 r=0 #MSG_RESUMING_PRINT c=0 r=0
"Resuming print"
"Druck fortgesetzt"
#MSG_RESUMING c=0 r=0
"Resuming print" "Resuming print"
"Druck fortgesetzt" "Druck fortgesetzt"

View file

@ -34,10 +34,6 @@
" of 4" " of 4"
" de 4" " de 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
" de 4"
#MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0
" of 9" " of 9"
" de 9" " de 9"
@ -182,11 +178,7 @@
"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
"Calibrando XYZ. Gira el boton para subir el extrusor hasta tocar los topes superiores. Despues haz clic." "Calibrando XYZ. Gira el boton para subir el extrusor hasta tocar los topes superiores. Despues haz clic."
#MSG_HOMEYZ_PROGRESS c=0 r=0 #MSG_CALIBRATE_Z_AUTO c=0 r=0
"Calibrating Z"
"Calibrando Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z" "Calibrating Z"
"Calibrando Z" "Calibrando Z"
@ -342,10 +334,6 @@
"Extruder" "Extruder"
"Extruir" "Extruir"
#MSG_MOVE_E c=0 r=0
"Extruder"
"Extruir"
#MSG_FSENS_AUTOLOAD_ON c=17 r=1 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
"F. autoload [on]" "F. autoload [on]"
"\x00" "\x00"
@ -1002,11 +990,7 @@
"Resume print" "Resume print"
"Reanudar impres." "Reanudar impres."
#MSG_RESUMING c=0 r=0 #MSG_RESUMING_PRINT c=0 r=0
"Resuming print"
"Resumiendo impresion"
#MSG_RESUMING c=0 r=0
"Resuming print" "Resuming print"
"Resumiendo impresion" "Resumiendo impresion"

View file

@ -34,10 +34,6 @@
" of 4" " of 4"
" su 4" " su 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
" su 4"
#MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0
" of 9" " of 9"
" su 9" " su 9"
@ -182,11 +178,7 @@
"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
"Calibrazione XYZ. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare." "Calibrazione XYZ. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare."
#MSG_HOMEYZ_PROGRESS c=0 r=0 #MSG_CALIBRATE_Z_AUTO c=0 r=0
"Calibrating Z"
"Calibrando Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z" "Calibrating Z"
"Calibrando Z" "Calibrando Z"
@ -342,10 +334,6 @@
"Extruder" "Extruder"
"Muovi Estrusore" "Muovi Estrusore"
#MSG_MOVE_E c=0 r=0
"Extruder"
"Muovi Estrusore"
#MSG_FSENS_AUTOLOAD_ON c=17 r=1 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
"F. autoload [on]" "F. autoload [on]"
"\x00" "\x00"
@ -1002,11 +990,7 @@
"Resume print" "Resume print"
"Riprendi stampa" "Riprendi stampa"
#MSG_RESUMING c=0 r=0 #MSG_RESUMING_PRINT c=0 r=0
"Resuming print"
"Riprendi stampa"
#MSG_RESUMING c=0 r=0
"Resuming print" "Resuming print"
"Riprendi stampa" "Riprendi stampa"

View file

@ -34,10 +34,6 @@
" of 4" " of 4"
" z 4" " z 4"
#MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
" of 4"
" z 4"
#MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0 #MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 c=14 r=0
" of 9" " of 9"
" z 9" " z 9"
@ -182,11 +178,7 @@
"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
"Kalibracja XYZ. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic." "Kalibracja XYZ. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic."
#MSG_HOMEYZ_PROGRESS c=0 r=0 #MSG_CALIBRATE_Z_AUTO c=0 r=0
"Calibrating Z"
"Kalibruje Z"
#MSG_HOMEYZ_PROGRESS c=0 r=0
"Calibrating Z" "Calibrating Z"
"Kalibruje Z" "Kalibruje Z"
@ -342,10 +334,6 @@
"Extruder" "Extruder"
"Extruder" "Extruder"
#MSG_MOVE_E c=0 r=0
"Extruder"
"Extruder"
#MSG_FSENS_AUTOLOAD_ON c=17 r=1 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
"F. autoload [on]" "F. autoload [on]"
"\x00" "\x00"
@ -1002,11 +990,7 @@
"Resume print" "Resume print"
"Kontynuowac" "Kontynuowac"
#MSG_RESUMING c=0 r=0 #MSG_RESUMING_PRINT c=0 r=0
"Resuming print"
"Wznowienie druku"
#MSG_RESUMING c=0 r=0
"Resuming print" "Resuming print"
"Wznowienie druku" "Wznowienie druku"

View file

@ -1,138 +1,160 @@
#!/bin/sh #!/bin/sh
# makelang.sh - multi-language support high-level script #
# for generating lang_xx.bin (secondary language binary file) # makelang.sh - multi-language support script
# # for generating lang_xx.bin (secondary language binary file)
# Input files: #
# lang_en.txt # Input files:
# lang_en_$LANG.txt # lang_en.txt
# # lang_en_$LANG.txt
# Output files: #
# lang_en.tmp (temporary, will be removed when finished) # Output files:
# lang_en_$LANG.tmp ==||== # lang_en.tmp (temporary, will be removed when finished)
# lang_en_$LANG.dif ==||== # lang_en_$LANG.tmp ==||==
# lang_$LANG.txt # lang_en_$LANG.dif ==||==
# # lang_$LANG.txt
# #
# Selected language: #
LANG=$1 # Selected language:
if [ -z "$LANG" ]; then LANG='cz'; fi LANG=$1
# if [ -z "$LANG" ]; then LANG='cz'; fi
# #
#
function finish
{ finish()
if [ "$1" == "0" ]; then {
if [ -e lang_en.tmp ]; then rm lang_en.tmp; fi if [ $1 -eq 0 ]; then
if [ -e lang_en_$LANG.tmp ]; then rm lang_en_$LANG.tmp; fi if [ -e lang_en.tmp ]; then rm lang_en.tmp; fi
if [ -e lang_en_$LANG.dif ]; then rm lang_en_$LANG.dif; fi if [ -e lang_en_$LANG.tmp ]; then rm lang_en_$LANG.tmp; fi
fi if [ -e lang_en_$LANG.dif ]; then rm lang_en_$LANG.dif; fi
echo fi
if [ "$1" == "0" ]; then # echo >&2
echo "make_lang.sh finished with success" >&2 if [ $1 -eq 0 ]; then
else echo "make_lang.sh finished with success" >&2
echo "make_lang.sh finished with errors!" >&2 else
fi echo "make_lang.sh finished with errors!" >&2
case "$-" in fi
*i*) echo "press enter key"; read ;; exit $1
esac }
exit $1
} make_lang()
{
echo "make_lang.sh started" >&2 LANG=$1
echo "selected language=$LANG" >&2
echo "make_lang.sh started" >&2
#check if input files exists echo "selected language=$LANG" >&2
echo -n " checking input files..." >&2
if [ ! -e lang_en.txt ]; then echo "NG! file lang_en.txt not found!" >&2; exit 1; fi #check if input files exists
if [ ! -e lang_en_$LANG.txt ]; then echo "NG! file lang_en_$LANG.txt not found!" >&2; exit 1; fi echo -n " checking input files..." >&2
echo "OK" >&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
#filter comment and empty lines from key and dictionary files, create temporary files echo "OK" >&2
echo -n " creating tmp files..." >&2
cat lang_en.txt | sed "/^$/d;/^#/d" > lang_en.tmp #filter comment and empty lines from key and dictionary files, create temporary files
cat lang_en_$LANG.txt | sed "/^$/d;/^#/d" > lang_en_$LANG.tmp echo -n " creating tmp files..." >&2
echo "OK" >&2 cat lang_en.txt | sed "/^$/d;/^#/d" > lang_en.tmp
#cat lang_en_$LANG.tmp | sed 'n;d' >test1.txt cat lang_en_$LANG.txt | sed "/^$/d;/^#/d" > lang_en_$LANG.tmp
echo "OK" >&2
#compare files using diff and check for differences #cat lang_en_$LANG.tmp | sed 'n;d' >test1.txt
echo -n " comparing tmp files..." >&2
if ! cat lang_en_$LANG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LANG.dif; then #compare files using diff and check for differences
echo "NG!" >&2 echo -n " comparing tmp files..." >&2
echo "Entries in lang_en_$LANG.txt are different from lang_en.txt!" >&2 if ! cat lang_en_$LANG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LANG.dif; then
echo "please check lang_en_$LANG.dif" >&2 echo "NG!" >&2
finish 1 echo "Entries in lang_en_$LANG.txt are different from lang_en.txt!" >&2
fi echo "please check lang_en_$LANG.dif" >&2
echo "OK" >&2 finish 1
fi
#generate lang_xx.txt (secondary language text data sorted by ids) echo "OK" >&2
echo -n " generating lang_$LANG.txt..." >&2
cat lang_en_$LANG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LANG.txt #generate lang_xx.txt (secondary language text data sorted by ids)
echo "OK" >&2 echo -n " generating lang_$LANG.txt..." >&2
cat lang_en_$LANG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LANG.txt
#generate lang_xx.dat (secondary language text data in binary form) echo "OK" >&2
echo -n " generating lang_$LANG.dat..." >&2
cat lang_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do #generate lang_xx.dat (secondary language text data in binary form)
s=${s#\"} echo -n " generating lang_$LANG.dat..." >&2
s=${s%\"} cat lang_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do
echo -n -e "$s"'\x00' s=${s#\"}
done >lang_$LANG.dat s=${s%\"}
echo "OK" >&2 /bin/echo -e -n "$s\x00"
done >lang_$LANG.dat
#calculate variables echo "OK" >&2
lt_magic='\xa5\x5a\xb4\x4b'
lt_count=$(grep -c '^' lang_$LANG.txt) #calculate variables
lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ') lt_magic='\xa5\x5a\xb4\x4b'
lt_offs_size=$((2 * $lt_count)) lt_count=$(grep -c '^' lang_$LANG.txt)
lt_size=$((16 + $lt_offs_size + $lt_data_size)) lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ')
lt_chsum=1 lt_offs_size=$((2 * $lt_count))
lt_resv0='\xff\xff' lt_size=$((16 + $lt_offs_size + $lt_data_size))
lt_resv1='\xff\xff\xff\xff' lt_chsum=1
lt_code='\xff\xff'
#generate lang_xx.ofs (secondary language text data offset table) lt_resv1='\xff\xff\xff\xff'
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" |\ case "$LANG" in
awk 'BEGIN { o='$((16 + $lt_offs_size))';} { printf("%d\n",o); o+=(length($0)-1); }' > lang_$LANG.ofs *en*) lt_code='\x6e\x65' ;;
echo "OK" >&2 *cz*) lt_code='\x73\x63' ;;
*de*) lt_code='\x65\x64' ;;
#generate lang_xx.bin (secondary language result binary file) *es*) lt_code='\x73\x65' ;;
echo " generating lang_$LANG.bin:" >&2 *it*) lt_code='\x74\x69' ;;
#create empty file *pl*) lt_code='\x6c\x70' ;;
dd if=/dev/zero of=lang_$LANG.bin bs=1 count=$lt_size 2>/dev/null esac
#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); }' #generate lang_xx.ofs (secondary language text data offset table)
echo -n " generating lang_$LANG.ofs..." >&2
#write data to binary file with dd 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 " writing header (16 bytes)..." >&2 echo "OK" >&2
echo -n -e "$lt_magic" |\
dd of=lang_$LANG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null #generate lang_xx.bin (secondary language result binary file)
echo -n -e $(echo -n "$lt_size" | awk "$awk_ui16") |\ echo " generating lang_$LANG.bin:" >&2
dd of=lang_$LANG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null #create empty file
echo -n -e $(echo -n "$lt_count" | awk "$awk_ui16") |\ dd if=/dev/zero of=lang_$LANG.bin bs=1 count=$lt_size 2>/dev/null
dd of=lang_$LANG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null #awk code to format ui16 variables for dd
echo -n -e $(echo -n "$lt_chsum" | awk "$awk_ui16") |\ awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }'
dd of=lang_$LANG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
echo -n -e "$lt_resv0" |\ #write data to binary file with dd
dd of=lang_$LANG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null
echo -n -e "$lt_resv1" |\ echo -n " writing header (16 bytes)..." >&2
dd of=lang_$LANG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null /bin/echo -n -e "$lt_magic" |\
echo "OK" >&2 dd of=lang_$LANG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null
/bin/echo -n -e $(echo -n "$lt_size" | awk "$awk_ui16") |\
echo -n " writing offset table ($lt_offs_size bytes)..." >&2 dd of=lang_$LANG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null
echo -n -e $(cat lang_$LANG.ofs | awk "$awk_ui16" | tr -d '\n'; echo) |\ /bin/echo -n -e $(echo -n "$lt_count" | awk "$awk_ui16") |\
dd of=./lang_$LANG.bin bs=1 count=$lt_offs_size seek=16 conv=notrunc 2>/dev/null dd of=lang_$LANG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null
echo "OK" >&2 /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
echo -n " writing text data ($lt_data_size bytes)..." >&2 /bin/echo -n -e "$lt_code" |\
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 of=lang_$LANG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null
echo "OK" >&2 /bin/echo -n -e "$lt_resv1" |\
dd of=lang_$LANG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null
echo " lang_table details:" >&2 echo "OK" >&2
echo " lt_count = $lt_count" >&2
echo " lt_size = $lt_size" >&2 echo -n " writing offset table ($lt_offs_size bytes)..." >&2
echo " lt_chsum = $lt_chsum" >&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
finish 0 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
echo "OK" >&2
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
if [ "$LANG" = "all" ]; then
make_lang cz
make_lang de
make_lang es
make_lang it
make_lang pl
exit 0
else
make_lang $LANG
fi
finish 0

1717
lang/po/lang.pot Normal file

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

View file

@ -1,61 +1,114 @@
#!/bin/sh #!/bin/sh
# #
# make_po.sh - multi-language support script # make_po.sh - multi-language support script
# for generating lang_xx.po # for generating lang_xx.po
# #
SRCDIR="../../Firmware" SRCDIR="../../Firmware"
# #
LANG=$1 LANG=$1
if [ -z "$LANG" ]; then LANG=cz; fi if [ -z "$LANG" ]; then LANG=cz; fi
# #
echo "make_po.sh started" >&2 if [ "$LANG" == "all" ]; then
./make_po.sh cz
#remove output file if exists ./make_po.sh de
if [ -e lang_$LANG.po ]; then rm lang_$LANG.po; fi ./make_po.sh es
./make_po.sh it
langname=$(\ ./make_po.sh pl
case "$LANG" in exit 0
*en*) echo "English" ;; fi
*cz*) echo "Czech" ;;
*de*) echo "German" ;; echo "make_po.sh started" >&2
*it*) echo "Italian" ;; echo " selected language=$LANG" >&2
*es*) echo "Spanish" ;;
*pl*) echo "Polish" ;; #remove output file if exists
esac) if [ -e lang_$LANG.po ]; then rm lang_$LANG.po; fi
#write po header lang_name=$(\
echo "# Translation into $langname." > lang_$LANG.po case "$LANG" in
echo "#" >> lang_$LANG.po *en*) echo "English" ;;
echo 'msgid ""' >> lang_$LANG.po *cz*) echo "Czech" ;;
echo 'msgstr ""' >> lang_$LANG.po *de*) echo "German" ;;
echo '"MIME-Version: 1.0\n"' >> lang_$LANG.po *es*) echo "Spanish" ;;
echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LANG.po *it*) echo "Italian" ;;
echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LANG.po *pl*) echo "Polish" ;;
echo >> lang_$LANG.po esac)
#list .cpp, .c and .h files lang_short=$(\
files=$(ls "$SRCDIR"/*.cpp "$SRCDIR"/*.c "$SRCDIR"/*.h) case "$LANG" in
*en*) echo "en" ;;
#loop over all messages, print only untranslated (=="\x00") *cz*) echo "cs" ;;
s0='' *de*) echo "de" ;;
s1='' *it*) echo "it" ;;
s2='' *es*) echo "es" ;;
cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g;s/^#/#: /" | while read -r s; do *pl*) echo "pl" ;;
if [ "$s" == "" ]; then esac)
if [ "$s0" == "\"\\\\x00\"" ]; then
search=$(echo -e "$s1") po_date=$(date)
found=$(grep -m1 -n -F "$search" $files | head -n1 | cut -f1-2 -d':' | sed "s/^.*\///")
echo "#: $found" #write po header
echo -e "msgid $s1" echo "# Translation of Prusa-Firmware into $lang_name." > lang_$LANG.po
echo 'msgstr ""' echo "#" >> lang_$LANG.po
echo echo 'msgid ""' >> lang_$LANG.po
fi echo 'msgstr ""' >> lang_$LANG.po
fi echo '"MIME-Version: 1.0\n"' >> lang_$LANG.po
s2=$s1 echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LANG.po
s1=$s0 echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LANG.po
s0=$s echo '"Language: '$lang_short'\n"' >> lang_$LANG.po
done >> lang_$LANG.po echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang_$LANG.po
echo '"POT-Creation-Date: '$po_date'\n"' >> lang_$LANG.po
echo "make_po.sh finished" >&2 echo '"PO-Revision-Date: '$po_date'\n"' >> lang_$LANG.po
exit 0 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
#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)
echo " $num_texts texts, $num_texts_nt not translated" >&2
#loop over all messages
s0=''
s1=''
s2=''
num=1
cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do
if [ "$s" == "" ]; then
echo " processing $num of $num_texts" >&2
if [ "$s0" == "\"\\\\x00\"" ]; then
search=$(/bin/echo -e "$s1")
found=$(grep -m1 -n -F "$search" $files | head -n1 | cut -f1-2 -d':' | sed "s/^.*\///")
echo "$s2" | sed 's/ c=0//;s/ r=0//;s/^#/# /'
echo "#: $found"
echo "#, fuzzy"
/bin/echo -e "msgid $s1"
echo 'msgstr ""'
echo
else
search=$(/bin/echo -e "$s1")
found=$(grep -m1 -n -F "$search" $files | head -n1 | cut -f1-2 -d':' | sed "s/^.*\///")
echo "$s2" | sed 's/ c=0//;s/ r=0//;s/^#/# /'
echo "#: $found"
/bin/echo -e "msgid $s1"
/bin/echo -e "msgstr $s0"
echo
fi
num=$((num+1))
fi
s2=$s1
s1=$s0
s0=$s
done >> lang_$LANG.po
#replace LF with CRLF
sync
sed -i 's/$/\r/' lang_$LANG.po
echo "make_po.sh finished" >&2
#read
exit 0

86
lang/po/make_pot.sh Normal file
View file

@ -0,0 +1,86 @@
#!/bin/sh
#
# make_pot.sh - multi-language support script
# Generate lang.pot
#
SRCDIR="../../Firmware"
#
#
echo "make_pot.sh started" >&2
#remove output file if exists
if [ -e lang.pot ]; then rm lang.pot; fi
lang_name="English"
lang_short="en"
po_date=$(date)
#cat ../lang_en_cz.txt | sed "/^$/d;/^#/d" | sed '{N;s/\n/ /}' | sed -n '/\"\\x00\"$/p' | sed 's/ \"\\x00\"$//' > lang_pot_cz.tmp
#cat ../lang_en_de.txt | sed "/^$/d;/^#/d" | sed '{N;s/\n/ /}' | sed -n '/\"\\x00\"$/p' | sed 's/ \"\\x00\"$//' > lang_pot_de.tmp
#cat ../lang_en_es.txt | sed "/^$/d;/^#/d" | sed '{N;s/\n/ /}' | sed -n '/\"\\x00\"$/p' | sed 's/ \"\\x00\"$//' > lang_pot_es.tmp
#cat ../lang_en_it.txt | sed "/^$/d;/^#/d" | sed '{N;s/\n/ /}' | sed -n '/\"\\x00\"$/p' | sed 's/ \"\\x00\"$//' > lang_pot_it.tmp
#cat ../lang_en_pl.txt | sed "/^$/d;/^#/d" | sed '{N;s/\n/ /}' | sed -n '/\"\\x00\"$/p' | sed 's/ \"\\x00\"$//' > lang_pot_pl.tmp
#cat lang_pot_cz.tmp lang_pot_de.tmp lang_pot_es.tmp lang_pot_it.tmp lang_pot_pl.tmp | sort -u > lang_pot.tmp
#cat ../lang_en.txt | sed "/^$/d;/^#/d" > lang_pot.tmp
#write po header
echo "# Translation of Prusa-Firmware into $lang_name." > lang.pot
echo "#" >> lang.pot
echo 'msgid ""' >> lang.pot
echo 'msgstr ""' >> lang.pot
echo '"MIME-Version: 1.0\n"' >> lang.pot
echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang.pot
echo '"Content-Transfer-Encoding: 8bit\n"' >> lang.pot
echo '"Language: '$lang_short'\n"' >> lang.pot
echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang.pot
echo '"POT-Creation-Date: '$po_date'\n"' >> lang.pot
echo '"PO-Revision-Date: '$po_date'\n"' >> lang.pot
echo '"Language-Team: \n"' >> lang.pot
echo '"X-Generator: Poedit 2.0.7\n"' >> lang.pot
echo '"X-Poedit-SourceCharset: UTF-8\n"' >> lang.pot
echo '"Last-Translator: \n"' >> lang.pot
echo '"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"' >> lang.pot
echo >> lang.pot
#list .cpp, .c and .h files
files=$(ls "$SRCDIR"/*.cpp "$SRCDIR"/*.c "$SRCDIR"/*.h)
num_texts=$(grep '^#' -c ../lang_en.txt)
#num_texts_nt=$(grep '^"' -c lang_en.txt)
#echo " $num_texts texts, $num_texts_nt not translated" >&2
echo " $num_texts texts" >&2
#loop over all messages
s0=''
s1=''
num=1
cat ../lang_en.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do
if [ -z "$s" ]; then
echo " processing $num of $num_texts" >&2
search=$(/bin/echo -e "$s0")
found=$(grep -m1 -n -F "$search" $files | head -n1 | cut -f1-2 -d':' | sed "s/^.*\///")
echo "$s1" | sed 's/ c=0//;s/ r=0//;s/^#/# /'
echo "#: $found"
#echo "#, fuzzy"
/bin/echo -e "msgid $s0"
echo 'msgstr ""'
echo
num=$((num+1))
fi
s1=$s0
s0=$s
done >> lang.pot
#replace LF with CRLF
sync
sed -i 's/$/\r/' lang.pot
echo "make_pot.sh finished" >&2
read
exit 0

View file

@ -1,116 +1,142 @@
#!/bin/sh #!/bin/sh
# postbuild.sh - multi-language support high-level script #
# for generating binary with secondary language # postbuild.sh - multi-language support script
# # Generate binary with secondary language.
# Input files: #
# $OUTDIR/Firmware.ino.elf # Input files:
# $OUTDIR/sketch/*.o (all object files) # $OUTDIR/Firmware.ino.elf
# # $OUTDIR/sketch/*.o (all object files)
# Output files: #
# text.sym # Output files:
# $PROGMEM.sym (progmem1.sym) # text.sym
# $PROGMEM.lss (...) # $PROGMEM.sym (progmem1.sym)
# $PROGMEM.hex # $PROGMEM.lss (...)
# $PROGMEM.chr # $PROGMEM.hex
# $PROGMEM.var # $PROGMEM.chr
# $PROGMEM.txt # $PROGMEM.var
# textaddr.txt # $PROGMEM.txt
# # textaddr.txt
# Output folder and elf file: #
OUTDIR="../../output" #
OUTELF="$OUTDIR/Firmware.ino.elf" # Config:
# if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
# AVR gcc tools used: if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
OBJCOPY=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objcopy.exe #
# # Selected language:
# Selected language: LANG=$1
LANG=$1 #if [ -z "$LANG" ]; then LANG='cz'; fi
#if [ -z "$LANG" ]; then LANG='cz'; fi #
# # Params:
# Params: IGNORE_MISSING_TEXT=1
IGNORE_MISSING_TEXT=1
function finish finish()
{ {
echo echo
if [ "$1" == "0" ]; then if [ "$1" = "0" ]; then
echo "postbuild.sh finished with success" >&2 echo "postbuild.sh finished with success" >&2
else else
echo "postbuild.sh finished with errors!" >&2 echo "postbuild.sh finished with errors!" >&2
fi fi
case "$-" in case "$-" in
*i*) echo "press enter key"; read ;; *i*) echo "press enter key"; read ;;
esac esac
exit $1 exit $1
} }
echo "postbuild.sh started" >&2 echo "postbuild.sh started" >&2
#check input files #check input files
echo " checking files:" >&2 echo " checking files:" >&2
if [ ! -e $OUTDIR ]; then echo " folder '$OUTDIR' not found!" >&2; finish 1; fi if [ ! -e $OUTDIR ]; then echo " folder '$OUTDIR' not found!" >&2; finish 1; fi
echo " folder OK" >&2 echo " folder OK" >&2
if [ ! -e $OUTELF ]; then echo " elf file '$OUTELF' not found!" >&2; finish 1; fi if [ ! -e $INOELF ]; then echo " elf file '$INOELF' not found!" >&2; finish 1; fi
echo " elf OK" >&2 echo " elf OK" >&2
if ! ls $OUTDIR/sketch/*.o >/dev/null 2>&1; then echo " no object files in '$OUTDIR/sketch/'!" >&2; finish 1; fi if ! ls $OBJDIR/*.o >/dev/null 2>&1; then echo " no object files in '$OBJDIR/'!" >&2; finish 1; fi
echo " objects OK" >&2 echo " objects OK" >&2
#run progmem.sh - examine content of progmem1 #run progmem.sh - examine content of progmem1
echo -n " running progmem.sh..." >&2 echo -n " running progmem.sh..." >&2
./progmem.sh 1 2>progmem.out ./progmem.sh 1 2>progmem.out
if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
echo "OK" >&2 echo "OK" >&2
#run textaddr.sh - map progmem addreses to text identifiers #run textaddr.sh - map progmem addreses to text identifiers
echo -n " running textaddr.sh..." >&2 echo -n " running textaddr.sh..." >&2
./textaddr.sh 2>textaddr.out ./textaddr.sh 2>textaddr.out
if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
echo "OK" >&2 echo "OK" >&2
#check for messages declared in progmem1, but not found in lang_en.txt #check for messages declared in progmem1, but not found in lang_en.txt
echo -n " checking textaddr.txt..." >&2 echo -n " checking textaddr.txt..." >&2
if cat textaddr.txt | grep "^ADDR NF" >/dev/null; then if cat textaddr.txt | grep "^ADDR NF" >/dev/null; then
echo "NG! - some texts not found in lang_en.txt!" echo "NG! - some texts not found in lang_en.txt!"
if [ $(("0$IGNORE_MISSING_TEXT")) -eq 0 ]; then if [ $IGNORE_MISSING_TEXT -eq 0 ]; then
finish 1 finish 1
else else
echo " missing text ignored!" >&2 echo " missing text ignored!" >&2
fi fi
else else
echo "OK" >&2 echo "OK" >&2
fi fi
#update progmem1 id entries in binary file #update progmem1 id entries in binary file
echo -n " extracting binary..." >&2 echo -n " extracting binary..." >&2
$OBJCOPY -I ihex -O binary $OUTDIR/Firmware.ino.hex ./firmware.bin $OBJCOPY -I ihex -O binary $INOHEX ./firmware.bin
echo "OK" >&2 echo "OK" >&2
#update binary file #update binary file
echo " updating binary:" >&2 echo " updating binary:" >&2
#update progmem1 id entries in binary file #update progmem1 id entries in binary file
echo -n " primary language ids..." >&2 echo -n " primary language ids..." >&2
cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\ cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\
awk '{ id = $2 - 1; hi = int(id / 256); lo = int(id - 256 * hi); printf("%d \\\\x%02x\\\\x%02x\n", strtonum($1), lo, hi); }' |\ awk '{ id = $2 - 1; hi = int(id / 256); lo = int(id - 256 * hi); printf("%d \\\\x%02x\\\\x%02x\n", strtonum($1), lo, hi); }' |\
while read addr data; do while read addr data; do
echo -n -e $data | dd of=./firmware.bin bs=1 count=2 seek=$addr conv=notrunc oflag=nonblock 2>/dev/null /bin/echo -n -e $data | dd of=./firmware.bin bs=1 count=2 seek=$addr conv=notrunc oflag=nonblock 2>/dev/null
done done
echo "OK" >&2 echo "OK" >&2
#update _SEC_LANG in binary file if language is selected #update _SEC_LANG in binary file if language is selected
echo -n " secondary language data..." >&2 echo -n " secondary language data..." >&2
if [ ! -z "$LANG" ]; then if [ ! -z "$LANG" ]; then
./update_lang.sh $LANG 2>./update_lang.out ./update_lang.sh $LANG 2>./update_lang.out
if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi
echo "OK" >&2 echo "OK" >&2
finish 0 finish 0
else else
echo "skipped" >&2 echo "Updating languages:" >&2
fi if [ -e lang_cz.bin ]; then
echo -n " Czech : " >&2
#convert bin to hex ./update_lang.sh cz 2>./update_lang_cz.out 1>/dev/null
echo -n " converting to hex..." >&2 if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex fi
echo "OK" >&2 if [ -e lang_de.bin ]; then
echo -n " German : " >&2
finish 0 ./update_lang.sh de 2>./update_lang_de.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
if [ -e lang_it.bin ]; then
echo -n " Italian: " >&2
./update_lang.sh it 2>./update_lang_it.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
if [ -e lang_es.bin ]; then
echo -n " Spanish: " >&2
./update_lang.sh es 2>./update_lang_es.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
if [ -e lang_pl.bin ]; then
echo -n " Polish : " >&2
./update_lang.sh pl 2>./update_lang_pl.out 1>/dev/null
if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; fi
fi
# echo "skipped" >&2
fi
#convert bin to hex
#echo -n " converting to hex..." >&2
#$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
#echo "OK" >&2
finish 0

View file

@ -1,127 +1,132 @@
#!/bin/sh #!/bin/sh
# progmem.sh - multi-language support low-level script #
# for examining content of progmem sections (default is progmem1) # progmem.sh - multi-language support script
# # Examine content of progmem sections (default is progmem1).
# Input files: #
# $OUTDIR/Firmware.ino.elf # Input files:
# $OUTDIR/sketch/*.o (all object files) # $OUTDIR/Firmware.ino.elf
# # $OUTDIR/sketch/*.o (all object files)
# Output files: #
# text.sym # Output files:
# $PROGMEM.sym # text.sym - formated symbol listing of section '.text'
# $PROGMEM.lss # $PROGMEM.sym - formated symbol listing of section '.progmemX'
# $PROGMEM.hex # $PROGMEM.lss - disassembly listing file
# $PROGMEM.chr # $PROGMEM.hex - variables - hex
# $PROGMEM.var # $PROGMEM.chr - variables - char escape
# $PROGMEM.txt # $PROGMEM.var - variables - strings
# # $PROGMEM.txt - text data only (not used)
# Program memory used #
PROGMEM=progmem$1 #
if [ -z "$1" ]; then PROGMEM=progmem1; fi # Config:
# if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
# Output folder and elf file: if [ -z "$OUTDIR" ]; then echo 'variable OUTDIR not set!' >&2; exit 1; fi
OUTDIR="../../output" if [ -z "$OBJDIR" ]; then echo 'variable OBJDIR not set!' >&2; exit 1; fi
OUTELF="$OUTDIR/Firmware.ino.elf" if [ -z "$INOELF" ]; then echo 'variable INOELF not set!' >&2; exit 1; fi
# if [ -z "$OBJDUMP" ]; then echo 'variable OBJDUMP not set!' >&2; exit 1; fi
# AVR gcc tools used: if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
OBJDUMP=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objdump.exe #
# # Program memory used
# PROGMEM=progmem$1
# Description of process: if [ -z "$1" ]; then PROGMEM=progmem1; fi
# 0. check input files #
# 1. remove output files # Description of process:
# 2. list symbol table of section '.text' from output elf file to text.sym (sorted by address) # 0. check input files
# 3. list symbol table of section '.$PROGMEM' from all output object files to $PROGMEM.sym # 1. remove output files
# 4. filter only $PROGMEM symbols from text.sym and store it back to $PROGMEM.sym with absolute address # 2. list symbol table of section '.text' from output elf file to text.sym (sorted by address)
# 5. calculate start and stop address of section '.$PROGMEM' # 3. list symbol table of section '.$PROGMEM' from all output object files to $PROGMEM.sym
# 6. extract string data from elf file to $PROGMEM.hex # 4. filter only $PROGMEM symbols from text.sym and store it back to $PROGMEM.sym with absolute address
# 7. prepare string data for character check and conversion (output to $PROGMEM.chr) # 5. calculate start and stop address of section '.$PROGMEM'
# 8. perform character check and conversion (output to $PROGMEM.var and $PROGMEM.txt) # 6. extract string data from elf file to $PROGMEM.hex
# # 7. prepare string data for character check and conversion (output to $PROGMEM.chr)
# 8. perform character check and conversion (output to $PROGMEM.var and $PROGMEM.txt)
echo "progmem.sh started" >&2 #
# (0) echo "progmem.sh started" >&2
echo " progmem.sh (0) - checking input files" >&2
if [ ! -e $OUTDIR ]; then echo "progmem.sh - file '$OUTELF' not found!" >&2; exit 1; fi # (0)
echo " progmem.sh (0) - checking input files" >&2
# (1) if [ ! -e $OUTDIR ]; then echo "progmem.sh - file '$INOELF' not found!" >&2; exit 1; fi
echo " progmem.sh (1) - removing output files" >&2
#remove output files if exists # (1)
if [ -e text.sym ]; then rm text.sym; fi echo " progmem.sh (1) - removing output files" >&2
if [ -e $PROGMEM.sym ]; then rm $PROGMEM.sym; fi #remove output files if exists
if [ -e $PROGMEM.lss ]; then rm $PROGMEM.lss; fi if [ -e text.sym ]; then rm text.sym; fi
if [ -e $PROGMEM.hex ]; then rm $PROGMEM.hex; fi if [ -e $PROGMEM.sym ]; then rm $PROGMEM.sym; fi
if [ -e $PROGMEM.chr ]; then rm $PROGMEM.chr; fi if [ -e $PROGMEM.lss ]; then rm $PROGMEM.lss; fi
if [ -e $PROGMEM.var ]; then rm $PROGMEM.var; fi if [ -e $PROGMEM.hex ]; then rm $PROGMEM.hex; fi
if [ -e $PROGMEM.txt ]; then rm $PROGMEM.txt; fi if [ -e $PROGMEM.chr ]; then rm $PROGMEM.chr; fi
if [ -e $PROGMEM.var ]; then rm $PROGMEM.var; fi
# (2) if [ -e $PROGMEM.txt ]; then rm $PROGMEM.txt; fi
echo " progmem.sh (2) - listing symbol table of section '.text'" >&2
#list symbols from section '.text' into file text.sym (only address, size and name) # (2)
$OBJDUMP -t -j ".text" $OUTELF | tail -n +5 | grep -E "^[0-9a-f]{8} [gl] O" | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> text.sym echo " progmem.sh (2) - listing symbol table of section '.text'" >&2
#list symbols from section '.text' into file text.sym (only address, size and name)
# (3) $OBJDUMP -t -j ".text" $INOELF | tail -n +5 | grep -E "^[0-9a-f]{8} [gl] O" | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> text.sym
echo " progmem.sh (3) - listing symbol table of section '.$PROGMEM'" >&2
#loop over all object files # (3)
ls "$OUTDIR"/sketch/*.o | while read fn; do echo " progmem.sh (3) - listing symbol table of section '.$PROGMEM'" >&2
echo " processing $fn" >&2 #loop over all object files
#list symbols from section $PROGMEM (only address, size and name) ls "$OBJDIR"/*.o | while read fn; do
$OBJDUMP -t -j ".$PROGMEM" $fn 2>/dev/null | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym echo " processing $fn" >&2
done #list symbols from section $PROGMEM (only address, size and name)
$OBJDUMP -t -j ".$PROGMEM" $fn 2>/dev/null | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym
# (4) done
echo " progmem.sh (4) - filtering $PROGMEM symbols" >&2
#create list of $PROGMEM symbol names separated by '\|' # (4)
progmem=$(cut -c19- $PROGMEM.sym) echo " progmem.sh (4) - filtering $PROGMEM symbols" >&2
progmem=$(echo $progmem | sed "s/ /\\\b\\\|\\\b/g") #create list of $PROGMEM symbol names separated by '\|'
progmem='\b'$progmem'\b' progmem=$(cut -c19- $PROGMEM.sym)
#filter $PROGMEM symbols from section '.text' (result file will contain list sorted by absolute address) progmem=$(echo $progmem | sed "s/ /\\\b\\\|\\\b/g")
cat text.sym | grep $progmem > $PROGMEM.sym progmem='\b'$progmem'\b'
#filter $PROGMEM symbols from section '.text' (result file will contain list sorted by absolute address)
# (5) cat text.sym | grep $progmem > $PROGMEM.sym
echo " progmem.sh (5) - calculating start and stop address" >&2
#calculate start addres of section ".$PROGMEM" # (5)
PROGMEM_BEG=$(head -n1 $PROGMEM.sym | while read offs size name; do echo "0x"$offs; done) echo " progmem.sh (5) - calculating start and stop address" >&2
#calculate stop addres of section ".$PROGMEM" #calculate start addres of section ".$PROGMEM"
PROGMEM_END=$(tail -n1 $PROGMEM.sym | while read offs size name; do printf "0x%x" $(("0x"$offs + "0x"$size)); done) PROGMEM_BEG=$(head -n1 $PROGMEM.sym | while read offs size name; do echo "0x"$offs; done)
echo " START address = "$PROGMEM_BEG >&2 #calculate stop addres of section ".$PROGMEM"
echo " STOP address = "$PROGMEM_END >&2 PROGMEM_END=$(tail -n1 $PROGMEM.sym | while read offs size name; do printf "0x%x" $((0x$offs + 0x$size)); done)
echo " START address = "$PROGMEM_BEG >&2
# (6) echo " STOP address = "$PROGMEM_END >&2
echo " progmem.sh (6) - extracting string data from elf" >&2
#dump $PROGMEM data in hex format, cut textual data (keep hex data only) # (6)
$OBJDUMP -d -j ".text" -w -z --start-address=$PROGMEM_BEG --stop-address=$PROGMEM_END $OUTELF | cut -c1-57 > $PROGMEM.lss echo " progmem.sh (6) - extracting string data from elf" >&2
#convert $PROGMEM.lss to $PROGMEM.hex: #dump $PROGMEM data in hex format, cut textual data (keep hex data only)
# replace empty lines with '|' (variables separated by empty lines) $OBJDUMP -d -j ".text" -w -z --start-address=$PROGMEM_BEG --stop-address=$PROGMEM_END $INOELF | cut -c1-57 > $PROGMEM.lss
# remove address from multiline variables (keep address at first variable line only) #convert $PROGMEM.lss to $PROGMEM.hex:
# remove '<' and '>:', remove whitespace at end of lines # replace empty lines with '|' (variables separated by empty lines)
# remove line-endings, replace separator with '\n' (join hex data lines - each line will contain single variable) # remove address from multiline variables (keep address at first variable line only)
# filter progmem symbols # remove '<' and '>:', remove whitespace at end of lines
cat $PROGMEM.lss | tail -n +7 | sed -E 's/^$/|/;s/^........:\t/ /;s/<//g;s/>:/ /g;s/[ \t]*$//' |\ # remove line-endings, replace separator with '\n' (join hex data lines - each line will contain single variable)
tr -d '\n' | sed "s/[|]/\n/g" | grep $progmem > $PROGMEM.hex # filter progmem symbols
cat $PROGMEM.lss | tail -n +7 | sed -E 's/^$/|/;s/^........:\t/ /;s/<//g;s/>:/ /g;s/[ \t]*$//' |\
# (7) tr -d '\n' | sed "s/[|]/\n/g" | grep $progmem > $PROGMEM.hex
echo " progmem.sh (7) - preparing string data" >&2
#convert $PROGMEM.hex to $PROGMEM.chr (prepare string data for character check and conversion) # (7)
# replace first space with tab echo " progmem.sh (7) - preparing string data" >&2
# replace second space with tab and space #convert $PROGMEM.hex to $PROGMEM.chr (prepare string data for character check and conversion)
# replace all remaining spaces with '\x' # replace first space with tab
# replace all tabs with spaces # replace second space with tab and space
cat $PROGMEM.hex | sed 's/ /\t/;s/ /\t /;s/ /\\x/g;s/\t/ /g' > $PROGMEM.chr # replace all remaining spaces with '\x'
# replace all tabs with spaces
# (8) cat $PROGMEM.hex | sed 's/ /\t/;s/ /\t /;s/ /\\x/g;s/\t/ /g' > $PROGMEM.chr
#convert $PROGMEM.chr to $PROGMEM.var (convert data to text)
echo " progmem.sh (8) - converting string data" >&2
cat $PROGMEM.chr | \ # (8)
sed 's/ \\xff\\xff/ /;' | \ #convert $PROGMEM.chr to $PROGMEM.var (convert data to text, TODO: rewrite as awk script)
sed 's/\\x22/\\\\\\x22/g;' | \ echo " progmem.sh (8) - converting string data" >&2
sed 's/\\x1b/\\\\\\x1b/g;' | \ cat $PROGMEM.chr | \
sed 's/\\x01/\\\\\\x01/g;' | \ sed 's/ \\xff\\xff/ /;' | \
sed 's/\\xf8/\\\\\\xf8/g;' | \ sed 's/\\x22/\\\\\\x22/g;' | \
sed 's/\\x00$/\\x0a/;s/^/printf "/;s/$/"/' | sh > $PROGMEM.var sed 's/\\x1b/\\\\\\x1b/g;' | \
cat $PROGMEM.var | sed 's/\r/\n/g' |sed -E 's/^[0-9a-f]{8} [^ ]* //' >$PROGMEM.txt sed 's/\\x01/\\\\\\x01/g;' | \
sed 's/\\xf8/\\\\\\xf8/g;' | \
echo "progmem.sh finished" >&2 sed 's/\\x00$//;s/^/\/bin\/echo -e "/;s/$/"/' | sh > $PROGMEM.var
#this step can be omitted because .txt file is not used
#cat $PROGMEM.var | sed 's/\r/\n/g' | sed -E 's/^[0-9a-f]{8} [^ ]* //' >$PROGMEM.txt
echo "progmem.sh finished" >&2
exit 0 exit 0

View file

@ -1,68 +1,68 @@
#!/bin/sh #!/bin/sh
# textaddr.sh - multi-language support low level script #
# for compiling progmem1.var and lang_en.txt files # textaddr.sh - multi-language support script
# to textaddr.txt file (mapping of progmem addreses to text idenifiers) # Compile progmem1.var and lang_en.txt files to textaddr.txt file (mapping of progmem addreses to text idenifiers)
# #
# Input files: # Input files:
# progmem1.var # progmem1.var
# lang_en.txt # lang_en.txt
# #
# Output files: # Output files:
# textaddr.txt # textaddr.txt
# #
# #
# Dscription of process: # Dscription of process:
# check if input files exists # check if input files exists
# create sorted list of strings from progmem1.var and lang_en.txt # create sorted list of strings from progmem1.var and lang_en.txt
# lines from progmem1.var will contain addres (8 chars) and english text # lines from progmem1.var will contain addres (8 chars) and english text
# lines from lang_en.txt will contain linenumber and english text # lines from lang_en.txt will contain linenumber and english text
# after sort this will generate pairs of lines (line from progmem1 first) # after sort this will generate pairs of lines (line from progmem1 first)
# result of sort is compiled with simple script and stored into file textaddr.txt # result of sort is compiled with simple script and stored into file textaddr.txt
# #
echo "textaddr.sh started" >&2 echo "textaddr.sh started" >&2
if [ ! -e progmem1.var ]; then echo 'textaddr.sh - file progmem1.var not found!' >&2; exit 1; fi if [ ! -e progmem1.var ]; then echo 'textaddr.sh - file progmem1.var not found!' >&2; exit 1; fi
if [ ! -e lang_en.txt ]; then echo 'textaddr.sh - file lang_en.txt not found!' >&2; exit 1; fi if [ ! -e lang_en.txt ]; then echo 'textaddr.sh - file lang_en.txt not found!' >&2; exit 1; fi
addr='' addr=''
text='' text=''
(cat progmem1.var | sed -E "s/^([^ ]*) ([^ ]*) (.*)/\1 \"\3\"/";\ (cat progmem1.var | sed -E "s/^([^ ]*) ([^ ]*) (.*)/\1 \"\3\"/";\
cat lang_en.txt | sed "/^$/d;/^#/d" | sed = | sed '{N;s/\n/ /}') |\ cat lang_en.txt | sed "/^$/d;/^#/d" | sed = | sed '{N;s/\n/ /}') |\
sort -k2 |\ sort -k2 |\
sed "s/\\\/\\\\\\\/g" | while read num txt; do sed "s/\\\/\\\\\\\/g" | while read num txt; do
if [ ${#num} -eq 8 ]; then if [ ${#num} -eq 8 ]; then
if [ -z "$addr" ]; then if [ -z "$addr" ]; then
addr=$num addr=$num
else else
if [ "$text" == "$txt" ]; then if [ "$text" = "$txt" ]; then
addr="$addr $num" addr="$addr $num"
else else
echo "ADDR NF $addr $text" echo "ADDR NF $addr $text"
addr=$num addr=$num
fi fi
fi fi
text=$txt text=$txt
else else
if [ -z "$addr" ]; then if [ -z "$addr" ]; then
echo "TEXT NF $num $txt" echo "TEXT NF $num $txt"
else else
if [ "$text" == "$txt" ]; then if [ "$text" = "$txt" ]; then
if [ ${#addr} -eq 8 ]; then if [ ${#addr} -eq 8 ]; then
echo "ADDR OK $addr $num" echo "ADDR OK $addr $num"
else else
echo "$addr" | sed "s/ /\n/g" | while read ad; do echo "$addr" | sed "s/ /\n/g" | while read ad; do
echo "ADDR OK $ad $num" echo "ADDR OK $ad $num"
done done
fi fi
addr='' addr=''
text='' text=''
else else
echo "TEXT NF $num $txt" echo "TEXT NF $num $txt"
fi fi
fi fi
fi fi
done > textaddr.txt done > textaddr.txt
echo "textaddr.sh finished" >&2 echo "textaddr.sh finished" >&2
exit 0 exit 0

View file

@ -1,68 +1,71 @@
#!/bin/sh #!/bin/sh
# update_lang.sh - multi-language support low level script #
# for updating secondary language in binary file # update_lang.sh - multi-language support script
# # Update secondary language in binary file.
# AVR gcc tools used: #
OBJCOPY=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objcopy.exe # Config:
# if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
# Selected language: if [ -z "$OBJCOPY" ]; then echo 'variable OBJCOPY not set!' >&2; exit 1; fi
LANG=$1 if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
if [ -z "$LANG" ]; then LANG='cz'; fi #
# # Selected language:
LANG=$1
function finish if [ -z "$LANG" ]; then LANG='cz'; fi
{ #
echo
if [ "$1" == "0" ]; then finish()
echo "update_lang.sh finished with success" >&2 {
else echo
echo "update_lang.sh finished with errors!" >&2 if [ "$1" = "0" ]; then
fi echo "update_lang.sh finished with success" >&2
case "$-" in else
*i*) echo "press enter key"; read ;; echo "update_lang.sh finished with errors!" >&2
esac fi
exit $1 case "$-" in
} *i*) echo "press enter key" >&2; read ;;
esac
echo "update_lang.sh started" >&2 exit $1
echo "selected language=$LANG" >&2 }
echo -n " checking files..." >&2 echo "update_lang.sh started" >&2
if [ ! -e text.sym ]; then echo "NG! file text.sym not found!" >&2; finish 1; fi echo " selected language=$LANG" >&2
if [ ! -e lang_$LANG.bin ]; then echo "NG! file lang_$LANG.bin not found!" >&2; finish 1; fi
if [ ! -e firmware.bin ]; then echo "NG! file firmware.bin not found!" >&2; finish 1; fi echo -n " checking files..." >&2
echo "OK" >&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
echo -n " checking symbols..." >&2 if [ ! -e firmware.bin ]; then echo "NG! file firmware.bin not found!" >&2; finish 1; fi
#find symbol _SEC_LANG in section '.text' echo "OK" >&2
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 echo -n " checking symbols..." >&2
echo "OK" >&2 #find symbol _SEC_LANG in section '.text'
sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b")
echo " calculating vars:" >&2 if [ -z "$sec_lang" ]; then echo "NG!\n symbol _SEC_LANG not found!" >&2; finish 1; fi
#get addres and size echo "OK" >&2
sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ') echo " calculating vars:" >&2
echo " sec_lang_addr =$sec_lang_addr" >&2 #get addres and size
echo " sec_lang_size =$sec_lang_size" >&2 sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
#calculate lang_table_addr (aligned to 256byte page) sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
lang_table_addr=$((256*$((($sec_lang_addr + 255) / 256)))) echo " sec_lang_addr =$sec_lang_addr" >&2
printf " lang_table_addr =0x%04x\n" $lang_table_addr >&2 echo " sec_lang_size =$sec_lang_size" >&2
#calculate lang_table_size #calculate lang_table_addr (aligned to 256byte page)
lang_table_size=$((256*$((($sec_lang_size - ($lang_table_addr - $sec_lang_addr))/256)))) lang_table_addr=$((256*$((($sec_lang_addr + 255) / 256))))
printf " lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2 printf " lang_table_addr =0x%04x\n" $lang_table_addr >&2
#calculate lang_table_size
#get lang_xx.bin file size lang_table_size=$((256*$((($sec_lang_size - ($lang_table_addr - $sec_lang_addr))/256))))
lang_file_size=$(wc -c lang_$LANG.bin | cut -f1 -d' ') printf " lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2
printf " lang_file_size =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2
#get lang_xx.bin file size
if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!"; finish 1; fi lang_file_size=$(wc -c lang_$LANG.bin | cut -f1 -d' ')
printf " lang_file_size =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2
echo "updating 'firmware.bin'..." >&2
dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi
#convert bin to hex echo "updating 'firmware.bin'..." >&2
echo "converting to hex..." >&2 dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
#convert bin to hex
finish 0 echo "converting to hex..." >&2
$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware_$LANG.hex
finish 0