commit
14a19d70f7
@ -1113,7 +1113,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes)
|
|||||||
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
|
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
|
||||||
printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum);
|
printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum);
|
||||||
printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
|
printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
|
||||||
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1);
|
printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature);
|
||||||
|
|
||||||
addr += header.size;
|
addr += header.size;
|
||||||
codes[count] = header.code;
|
codes[count] = header.code;
|
||||||
@ -1190,7 +1190,7 @@ void setup()
|
|||||||
#ifdef DEBUG_SEC_LANG
|
#ifdef DEBUG_SEC_LANG
|
||||||
lang_table_header_t header;
|
lang_table_header_t header;
|
||||||
uint32_t src_addr = 0x00000;
|
uint32_t src_addr = 0x00000;
|
||||||
if (lang_get_header(3, &header, &src_addr))
|
if (lang_get_header(1, &header, &src_addr))
|
||||||
{
|
{
|
||||||
//this is comparsion of some printing-methods regarding to flash space usage and code size/readability
|
//this is comparsion of some printing-methods regarding to flash space usage and code size/readability
|
||||||
#define LT_PRINT_TEST 2
|
#define LT_PRINT_TEST 2
|
||||||
@ -1207,7 +1207,7 @@ void setup()
|
|||||||
printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
|
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_chsum = 0x%04x\n"), header.checksum);
|
||||||
printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
|
printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
|
||||||
printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1);
|
printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature);
|
||||||
#elif (LT_PRINT_TEST==2) //optimized printf
|
#elif (LT_PRINT_TEST==2) //optimized printf
|
||||||
printf_P(
|
printf_P(
|
||||||
_n(
|
_n(
|
||||||
@ -1225,7 +1225,7 @@ void setup()
|
|||||||
header.count, header.count,
|
header.count, header.count,
|
||||||
header.checksum,
|
header.checksum,
|
||||||
header.code, header.code >> 8, header.code & 0xff,
|
header.code, header.code >> 8, header.code & 0xff,
|
||||||
header.reserved1
|
header.signature
|
||||||
);
|
);
|
||||||
#elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved)
|
#elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved)
|
||||||
MYSERIAL.print(" _src_addr = 0x");
|
MYSERIAL.print(" _src_addr = 0x");
|
||||||
@ -1252,7 +1252,7 @@ void setup()
|
|||||||
MYSERIAL.print((char)(header.code & 0xff), 0);
|
MYSERIAL.print((char)(header.code & 0xff), 0);
|
||||||
MYSERIAL.println(")");
|
MYSERIAL.println(")");
|
||||||
MYSERIAL.print(" _lt_resv1 = 0x");
|
MYSERIAL.print(" _lt_resv1 = 0x");
|
||||||
MYSERIAL.println(header.reserved1, 16);
|
MYSERIAL.println(header.signature, 16);
|
||||||
#endif //(LT_PRINT_TEST==)
|
#endif //(LT_PRINT_TEST==)
|
||||||
#undef LT_PRINT_TEST
|
#undef LT_PRINT_TEST
|
||||||
|
|
||||||
@ -1265,7 +1265,22 @@ void setup()
|
|||||||
if ((i % 16) == 15) putchar('\n');
|
if ((i % 16) == 15) putchar('\n');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
uint16_t sum = 0;
|
||||||
|
for (uint16_t i = 0; i < header.size; i++)
|
||||||
|
sum += (uint16_t)pgm_read_byte((uint8_t*)(_SEC_LANG_TABLE + i)) << ((i & 1)?0:8);
|
||||||
|
printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
|
||||||
|
sum -= header.checksum; //subtract checksum
|
||||||
|
printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
|
||||||
|
sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
|
||||||
|
if (sum == header.checksum)
|
||||||
|
printf_P(_n("Checksum OK\n"), sum);
|
||||||
|
else
|
||||||
|
printf_P(_n("Checksum NG\n"), sum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf_P(_n("lang_get_header failed!\n"));
|
||||||
|
|
||||||
|
#if 0
|
||||||
for (uint16_t i = 0; i < 1024*10; i++)
|
for (uint16_t i = 0; i < 1024*10; i++)
|
||||||
{
|
{
|
||||||
if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i);
|
if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i);
|
||||||
@ -1273,10 +1288,6 @@ void setup()
|
|||||||
if ((i % 16) == 15) putchar('\n');
|
if ((i % 16) == 15) putchar('\n');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
printf_P(_n("lang_get_header failed!\n"));
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
SERIAL_ECHOLN("Reading eeprom from 0 to 100: start");
|
SERIAL_ECHOLN("Reading eeprom from 0 to 100: start");
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
//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
|
||||||
#define LANG_SIZE_RESERVED 0x2700 // reserved space for secondary language (~10kb)
|
#define LANG_SIZE_RESERVED 0x2400 // reserved space for secondary language (~10kb)
|
||||||
//#define LANG_SIZE_RESERVED 0x1ef8 // reserved space for secondary language (~10kb)
|
//#define LANG_SIZE_RESERVED 0x1ef8 // reserved space for secondary language (~10kb)
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ uint8_t lang_is_selected(void) { return 1; }
|
|||||||
//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";
|
||||||
|
|
||||||
|
//primary language signature
|
||||||
|
const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff};
|
||||||
|
|
||||||
//lang_table pointer
|
//lang_table pointer
|
||||||
lang_table_t* lang_table = 0;
|
lang_table_t* lang_table = 0;
|
||||||
|
|
||||||
@ -56,8 +59,12 @@ uint8_t lang_select(uint8_t lang)
|
|||||||
{
|
{
|
||||||
if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
|
if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
|
||||||
{
|
{
|
||||||
lang_table = _SEC_LANG_TABLE; // set table pointer
|
if (lang_check(_SEC_LANG_TABLE))
|
||||||
lang_selected = lang; // set language id
|
if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
|
||||||
|
{
|
||||||
|
lang_table = _SEC_LANG_TABLE; // set table pointer
|
||||||
|
lang_selected = lang; // set language id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else //W25X20CL
|
#else //W25X20CL
|
||||||
@ -70,6 +77,18 @@ uint8_t lang_select(uint8_t lang)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t lang_check(uint16_t addr)
|
||||||
|
{
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint16_t size = pgm_read_word((uint16_t*)(addr + 4));
|
||||||
|
uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8));
|
||||||
|
uint16_t i; for (i = 0; i < size; i++)
|
||||||
|
sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8);
|
||||||
|
sum -= lt_sum; //subtract checksum
|
||||||
|
sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
|
||||||
|
return (sum == lt_sum);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t lang_get_count()
|
uint8_t lang_get_count()
|
||||||
{
|
{
|
||||||
#ifdef W25X20CL
|
#ifdef W25X20CL
|
||||||
@ -98,7 +117,7 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
|
|||||||
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
||||||
memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
|
memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
|
||||||
if (offset) *offset = ui;
|
if (offset) *offset = ui;
|
||||||
return (header == LANG_MAGIC)?1:0; //return 1 if magic valid
|
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
|
||||||
}
|
}
|
||||||
W25X20CL_SPI_ENTER();
|
W25X20CL_SPI_ENTER();
|
||||||
uint32_t addr = 0x00000; //start of xflash
|
uint32_t addr = 0x00000; //start of xflash
|
||||||
|
@ -52,7 +52,7 @@ typedef struct
|
|||||||
uint16_t count; //+6
|
uint16_t count; //+6
|
||||||
uint16_t checksum; //+8
|
uint16_t checksum; //+8
|
||||||
uint16_t code; //+10
|
uint16_t code; //+10
|
||||||
uint32_t reserved1; //+12
|
uint32_t signature; //+12
|
||||||
} lang_table_header_t;
|
} lang_table_header_t;
|
||||||
|
|
||||||
//lang_table_t structure - (size= 16byte + 2*count)
|
//lang_table_t structure - (size= 16byte + 2*count)
|
||||||
@ -98,10 +98,13 @@ extern uint8_t lang_selected;
|
|||||||
extern const char _SEC_LANG[LANG_SIZE_RESERVED];
|
extern const char _SEC_LANG[LANG_SIZE_RESERVED];
|
||||||
extern const char* lang_get_translation(const char* s);
|
extern const char* lang_get_translation(const char* s);
|
||||||
#define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00)
|
#define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00)
|
||||||
|
//extern const uint32_t _PRI_LANG_SIGNATURE;
|
||||||
#endif //(LANG_MODE != 0)
|
#endif //(LANG_MODE != 0)
|
||||||
|
|
||||||
//selects language, eeprom is updated in case of success
|
//selects language, eeprom is updated in case of success
|
||||||
extern uint8_t lang_select(uint8_t lang);
|
extern uint8_t lang_select(uint8_t lang);
|
||||||
|
//performs checksum test of secondary language data
|
||||||
|
extern uint8_t lang_check(uint16_t addr);
|
||||||
//returns total number of languages (primary + all in xflash)
|
//returns total number of languages (primary + all in xflash)
|
||||||
extern uint8_t lang_get_count(void);
|
extern uint8_t lang_get_count(void);
|
||||||
//reads lang table header and offset in xflash or progmem
|
//reads lang table header and offset in xflash or progmem
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "Marlin.h"
|
#include "Marlin.h"
|
||||||
#include "w25x20cl.h"
|
#include "w25x20cl.h"
|
||||||
#include "stk500.h"
|
#include "stk500.h"
|
||||||
|
#include "bootapp.h"
|
||||||
|
|
||||||
#define OPTIBOOT_MAJVER 6
|
#define OPTIBOOT_MAJVER 6
|
||||||
#define OPTIBOOT_CUSTOMVER 0
|
#define OPTIBOOT_CUSTOMVER 0
|
||||||
@ -98,6 +99,7 @@ extern struct block_t *block_buffer;
|
|||||||
|
|
||||||
void optiboot_w25x20cl_enter()
|
void optiboot_w25x20cl_enter()
|
||||||
{
|
{
|
||||||
|
if (boot_app_flags & BOOT_APP_FLG_USER0) return;
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
uint8_t rampz = 0;
|
uint8_t rampz = 0;
|
||||||
register uint16_t address = 0;
|
register uint16_t address = 0;
|
||||||
|
@ -3682,11 +3682,18 @@ void lcd_set_progress() {
|
|||||||
static void lcd_language_menu()
|
static void lcd_language_menu()
|
||||||
{
|
{
|
||||||
START_MENU();
|
START_MENU();
|
||||||
if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0);
|
if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); //
|
||||||
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0);
|
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); //primary language
|
||||||
// MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1);
|
uint8_t cnt = lang_get_count();
|
||||||
for (int i = 2; i < lang_get_count(); i++) //skip seconday language - solved in lang_select
|
#ifdef W25X20CL
|
||||||
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i);
|
if (cnt == 2) //display secondary language in case of clear xflash
|
||||||
|
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1);
|
||||||
|
else
|
||||||
|
for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select (MK3)
|
||||||
|
#else //W25X20CL
|
||||||
|
for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
|
||||||
|
#endif //W25X20CL
|
||||||
|
MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i);
|
||||||
END_MENU();
|
END_MENU();
|
||||||
}
|
}
|
||||||
#endif //(LANG_MODE != 0)
|
#endif //(LANG_MODE != 0)
|
||||||
|
@ -86,7 +86,7 @@ lt_count=$(grep -c '^' lang_$LANG.txt)
|
|||||||
lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ')
|
lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ')
|
||||||
lt_offs_size=$((2 * $lt_count))
|
lt_offs_size=$((2 * $lt_count))
|
||||||
lt_size=$((16 + $lt_offs_size + $lt_data_size))
|
lt_size=$((16 + $lt_offs_size + $lt_data_size))
|
||||||
lt_chsum=1
|
lt_chsum=0
|
||||||
lt_code='\xff\xff'
|
lt_code='\xff\xff'
|
||||||
lt_resv1='\xff\xff\xff\xff'
|
lt_resv1='\xff\xff\xff\xff'
|
||||||
|
|
||||||
@ -138,6 +138,11 @@ echo -n " writing text data ($lt_data_size bytes)..." >&2
|
|||||||
dd if=./lang_$LANG.dat of=./lang_$LANG.bin bs=1 count=$lt_data_size seek=$((16 + $lt_offs_size)) conv=notrunc 2>/dev/null
|
dd if=./lang_$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 "OK" >&2
|
||||||
|
|
||||||
|
#calculate and update checksum
|
||||||
|
lt_chsum=$(cat lang_$LANG.bin | xxd | cut -c11-49 | tr ' ' "\n" | sed '/^$/d' | awk 'BEGIN { sum = 0; } { sum += strtonum("0x"$1); if (sum > 0xffff) sum -= 0x10000; } END { printf("%x\n", sum); }')
|
||||||
|
/bin/echo -n -e $(echo -n $((0x$lt_chsum)) | awk "$awk_ui16") |\
|
||||||
|
dd of=lang_$LANG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
|
||||||
|
|
||||||
echo " lang_table details:" >&2
|
echo " lang_table details:" >&2
|
||||||
echo " lt_count = $lt_count" >&2
|
echo " lt_count = $lt_count" >&2
|
||||||
echo " lt_size = $lt_size" >&2
|
echo " lt_size = $lt_size" >&2
|
||||||
|
@ -40,9 +40,15 @@ echo -n " checking symbols..." >&2
|
|||||||
#find symbol _SEC_LANG in section '.text'
|
#find symbol _SEC_LANG in section '.text'
|
||||||
sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b")
|
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
|
if [ -z "$sec_lang" ]; then echo "NG!\n symbol _SEC_LANG not found!" >&2; finish 1; fi
|
||||||
|
#find symbol _PRI_LANG_SIGNATURE in section '.text'
|
||||||
|
pri_lang=$(cat text.sym | grep -E "\b_PRI_LANG_SIGNATURE\b")
|
||||||
|
if [ -z "$pri_lang" ]; then echo "NG!\n symbol _PRI_LANG_SIGNATURE not found!" >&2; finish 1; fi
|
||||||
echo "OK" >&2
|
echo "OK" >&2
|
||||||
|
|
||||||
echo " calculating vars:" >&2
|
echo " calculating vars:" >&2
|
||||||
|
#get pri_lang addres
|
||||||
|
pri_lang_addr='0x'$(echo $pri_lang | cut -f1 -d' ')
|
||||||
|
echo " pri_lang_addr =$pri_lang_addr" >&2
|
||||||
#get addres and size
|
#get addres and size
|
||||||
sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
|
sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
|
||||||
sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
|
sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
|
||||||
@ -62,6 +68,7 @@ printf " lang_file_size =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size
|
|||||||
if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi
|
if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi
|
||||||
|
|
||||||
echo "updating 'firmware.bin'..." >&2
|
echo "updating 'firmware.bin'..." >&2
|
||||||
|
|
||||||
dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
|
dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
|
||||||
|
|
||||||
#convert bin to hex
|
#convert bin to hex
|
||||||
|
Loading…
Reference in New Issue
Block a user