From 7619e94040a1d4bc8915de1487d2ea106a327270 Mon Sep 17 00:00:00 2001 From: Robert Pelnar Date: Fri, 15 Jun 2018 20:37:33 +0200 Subject: [PATCH] New ML support - checksum and signature --- Firmware/Marlin_main.cpp | 31 +++++++++++++++++++++---------- Firmware/language.c | 25 ++++++++++++++++++++++--- Firmware/language.h | 5 ++++- Firmware/ultralcd.cpp | 8 ++++---- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index e984f821e..c98a42ac4 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -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_chsum = 0x%04x\n"), header.checksum); printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff); - printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1); + printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature); addr += header.size; codes[count] = header.code; @@ -1190,7 +1190,7 @@ void setup() #ifdef DEBUG_SEC_LANG lang_table_header_t header; uint32_t src_addr = 0x00000; - if (lang_get_header(3, &header, &src_addr)) + if (lang_get_header(1, &header, &src_addr)) { //this is comparsion of some printing-methods regarding to flash space usage and code size/readability #define LT_PRINT_TEST 2 @@ -1207,7 +1207,7 @@ void setup() printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count); printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum); printf_P(_n(" _lt_code = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff); - printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1); + printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature); #elif (LT_PRINT_TEST==2) //optimized printf printf_P( _n( @@ -1225,7 +1225,7 @@ void setup() header.count, header.count, header.checksum, header.code, header.code >> 8, header.code & 0xff, - header.reserved1 + header.signature ); #elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved) MYSERIAL.print(" _src_addr = 0x"); @@ -1252,7 +1252,7 @@ void setup() MYSERIAL.print((char)(header.code & 0xff), 0); MYSERIAL.println(")"); MYSERIAL.print(" _lt_resv1 = 0x"); - MYSERIAL.println(header.reserved1, 16); + MYSERIAL.println(header.signature, 16); #endif //(LT_PRINT_TEST==) #undef LT_PRINT_TEST @@ -1265,7 +1265,22 @@ void setup() if ((i % 16) == 15) putchar('\n'); } #endif -#if 1 + uint16_t sum = 0; + for (uint16_t i = 0; i < header.size; i++) + sum += (uint16_t)pgm_read_byte((uint8_t*)(_SEC_LANG_TABLE + i)) << ((i & 1)?0:8); + printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum); + sum -= header.checksum; //subtract checksum + printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum); + sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes + if (sum == header.checksum) + printf_P(_n("Checksum OK\n"), sum); + else + printf_P(_n("Checksum NG\n"), sum); + } + else + printf_P(_n("lang_get_header failed!\n")); + +#if 0 for (uint16_t i = 0; i < 1024*10; i++) { if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i); @@ -1273,10 +1288,6 @@ void setup() if ((i % 16) == 15) putchar('\n'); } #endif - } - else - printf_P(_n("lang_get_header failed!\n")); - #if 0 SERIAL_ECHOLN("Reading eeprom from 0 to 100: start"); diff --git a/Firmware/language.c b/Firmware/language.c index acac7d1bb..b79da8ff2 100644 --- a/Firmware/language.c +++ b/Firmware/language.c @@ -28,6 +28,9 @@ uint8_t lang_is_selected(void) { return 1; } //reserved xx kbytes for secondary language table const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG"; +//primary language signature +const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff}; + //lang_table pointer lang_table_t* lang_table = 0; @@ -56,8 +59,12 @@ uint8_t lang_select(uint8_t lang) { if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid { - lang_table = _SEC_LANG_TABLE; // set table pointer - lang_selected = lang; // set language id + if (lang_check(_SEC_LANG_TABLE)) + if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid + { + lang_table = _SEC_LANG_TABLE; // set table pointer + lang_selected = lang; // set language id + } } } #else //W25X20CL @@ -70,6 +77,18 @@ uint8_t lang_select(uint8_t lang) return 0; } +uint8_t lang_check(uint16_t addr) +{ + uint16_t sum = 0; + uint16_t size = pgm_read_word((uint16_t*)(addr + 4)); + uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8)); + uint16_t i; for (i = 0; i < size; i++) + sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8); + sum -= lt_sum; //subtract checksum + sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes + return (sum == lt_sum); +} + uint8_t lang_get_count() { #ifdef W25X20CL @@ -98,7 +117,7 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off uint16_t ui = _SEC_LANG_TABLE; //table pointer memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem if (offset) *offset = ui; - return (header == LANG_MAGIC)?1:0; //return 1 if magic valid + return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid } W25X20CL_SPI_ENTER(); uint32_t addr = 0x00000; //start of xflash diff --git a/Firmware/language.h b/Firmware/language.h index 359bc083a..509b0bc6d 100644 --- a/Firmware/language.h +++ b/Firmware/language.h @@ -52,7 +52,7 @@ typedef struct uint16_t count; //+6 uint16_t checksum; //+8 uint16_t code; //+10 - uint32_t reserved1; //+12 + uint32_t signature; //+12 } lang_table_header_t; //lang_table_t structure - (size= 16byte + 2*count) @@ -98,10 +98,13 @@ extern uint8_t lang_selected; extern const char _SEC_LANG[LANG_SIZE_RESERVED]; extern const char* lang_get_translation(const char* s); #define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00) +//extern const uint32_t _PRI_LANG_SIGNATURE; #endif //(LANG_MODE != 0) //selects language, eeprom is updated in case of success extern uint8_t lang_select(uint8_t lang); +//performs checksum test of secondary language data +extern uint8_t lang_check(uint16_t addr); //returns total number of languages (primary + all in xflash) extern uint8_t lang_get_count(void); //reads lang table header and offset in xflash or progmem diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0867d4397..74e0b349a 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3682,16 +3682,16 @@ void lcd_set_progress() { static void lcd_language_menu() { START_MENU(); - if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); - MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); + if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0); // + MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0); //primary language uint8_t cnt = lang_get_count(); #ifdef W25X20CL if (cnt == 2) //display secondary language in case of clear xflash MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1); else - for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select + 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 + 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();