2018-05-22 01:20:03 +00:00
|
|
|
//language.c
|
|
|
|
#include "language.h"
|
|
|
|
#include <avr/pgmspace.h>
|
2022-02-05 23:25:51 +00:00
|
|
|
#include <avr/io.h>
|
2018-06-10 14:04:32 +00:00
|
|
|
#include <avr/eeprom.h>
|
2018-05-29 19:03:47 +00:00
|
|
|
#include "bootapp.h"
|
2018-05-22 01:20:03 +00:00
|
|
|
|
2018-06-10 14:04:32 +00:00
|
|
|
#include "Configuration.h"
|
2018-06-21 17:58:13 +00:00
|
|
|
#include "pins.h"
|
2018-05-22 01:20:03 +00:00
|
|
|
|
2021-03-05 07:51:23 +00:00
|
|
|
#ifdef XFLASH
|
|
|
|
#include "xflash.h"
|
2021-06-08 13:20:23 +00:00
|
|
|
#include "xflash_layout.h"
|
2021-03-05 07:51:23 +00:00
|
|
|
#endif //XFLASH
|
2018-06-07 22:20:28 +00:00
|
|
|
|
|
|
|
// Currently active language selection.
|
2018-05-30 17:29:52 +00:00
|
|
|
uint8_t lang_selected = 0;
|
2018-05-22 01:20:03 +00:00
|
|
|
|
2018-06-07 22:20:28 +00:00
|
|
|
|
2018-05-22 01:20:03 +00:00
|
|
|
#if (LANG_MODE == 0) //primary language only
|
2018-06-07 22:20:28 +00:00
|
|
|
|
2020-09-11 13:12:49 +00:00
|
|
|
uint8_t lang_select(_UNUSED uint8_t lang) { return 0; }
|
2018-06-07 22:20:28 +00:00
|
|
|
uint8_t lang_get_count() { return 1; }
|
2020-09-11 13:12:49 +00:00
|
|
|
uint16_t lang_get_code(_UNUSED uint8_t lang) { return LANG_CODE_EN; }
|
|
|
|
const char* lang_get_name_by_code(_UNUSED uint16_t code) { return _n("English"); }
|
2018-06-10 14:28:15 +00:00
|
|
|
void lang_reset(void) { }
|
|
|
|
uint8_t lang_is_selected(void) { return 1; }
|
2018-06-07 22:20:28 +00:00
|
|
|
|
|
|
|
#else //(LANG_MODE == 0) //secondary languages in progmem or xflash
|
|
|
|
|
2018-05-22 01:20:03 +00:00
|
|
|
//reserved xx kbytes for secondary language table
|
2022-02-05 23:25:51 +00:00
|
|
|
const char _SEC_LANG[LANG_SIZE_RESERVED] __attribute__((aligned(SPM_PAGESIZE))) PROGMEM_I2 = "_SEC_LANG";
|
2018-05-22 01:20:03 +00:00
|
|
|
|
2018-06-15 18:37:33 +00:00
|
|
|
//primary language signature
|
|
|
|
const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff};
|
|
|
|
|
2018-05-22 01:20:03 +00:00
|
|
|
//lang_table pointer
|
|
|
|
lang_table_t* lang_table = 0;
|
|
|
|
|
|
|
|
const char* lang_get_translation(const char* s)
|
|
|
|
{
|
2018-06-07 22:20:28 +00:00
|
|
|
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, return orig. str.
|
2018-05-22 01:20:03 +00:00
|
|
|
uint16_t ui = pgm_read_word(((uint16_t*)s)); //read string id
|
New PO-based language translation support (#3471)
* lang: Add a PO language extractor with FW metadata support
Implement a straight-to-po language extractor which supports our custom
language requirements:
- _i/_I/ISTR for text string definitions
- _T for catalog translations (with back-reference support)
- //// EOL comments with:
- MSG_ catalog entry name identifiers
- c=X r=Y annotations for screen dimensioning checks
- Crude support for commented lines
All source locations are correctly referenced in the PO, with the
metadata colleted in the comment for further processing.
Several checks are implemented already during extraction:
- Correct catalog name assignment (no duplicates)
- Metadata checks for each entry
Further checks will be implemented by directly checking the translated PO file.
Requires "polib" and "regex" python modules.
* lang: Adapt lang-check to work directly on PO/POT files
* lang: Allow lang-extract to generate stable (pre-sorted) output directly
* lang: Further extend lang-extract consistency/error checking
- Do not parse inside preprocessor conditionals
- Distinguish between references and definitions
- Warn about missing references and definitions
* lang: lang-extract: warn about incorrect PROGMEM assignments
Check that ISTR is used along with PROGMEM_I1 in an attempt to spot
useless translated catalogs.
* lang: lang-extract: Improved handling of same-line translations
Correctly reference metadata on same-line translations.
* lang: lang-extract: Handle _O as a cat-ref
https://github.com/prusa3d/Prusa-Firmware/pull/3434
* lang: lang-extract: Warn about unused catalog definitions
* lang: lang-extract: Allow propagating translation comments via //
The definition:
code //// definition [// comment]
will check [definition] as before, but blindly accumulate // comment.
The comment is then re-appended back into the PO files for translators
with the form:
definition
comment
comment...
* lang: Fix incorrect display definitions
* lang: lang-extract: Check source encoding/charmap
* lang: Translate the degree symbol
* lang: Unbreak/cleanup DEBUG_SEC_LANG
* lang: Improve meaning of comment
* lang: Split charset conversions into an aux lib for future use
* lang: Implement lang-map.py to extract the translation symbol map
- Extracts the translatable symbol map for further use
- Computes a stable "language signature" from the map itself
- Optionally patches the binary update the symbols
* lang: Check for translation recoding problems
* lang: Implement a transliteration map to post-process translations
TRANS_CHARS is now used to replace unavailable symbols to the source
encoding, only while producing the language catalog.
* lang: Handle/check character replacements in lang-check
Filter the translation through TRANS_CHARS, so that the preview and
length check are performed correctly for expanding replacements such as
'ß' to 'ss'.
* lang: Implement lang-build.py to generate the final language catalog
* Cleanup .gitignore
* lang: Drop txt language files
* lang: Remove outdated translation scripts and obsolete docs
* lang: Update build scripts for new infrastructure
* lang: [no] Integrate accents from po/new/no.po
We now support accents natively
* lang: Remove redundant directory po/new/
* lang: Fix encoding of LCD characters in PO files
* lang: [hr] Fix wrapping in MSG_CRASH_DET_ONLY_IN_NORMAL
* lang: Sort and reformat PO files for further massaging
* lang: Switch to developer (dot) comments for PO metadata
* lang: Allow the IGNORE annotation to skip extraction
* lang: Fix missing/broken language metadata in sources
* lang: Add update-pot.sh and regenerate po/Firmware.pot
* lang: Add update-po.sh and refresh all PO files
* lang: Add summary documentation about the new translation workflow
* Add more ignored files
* CI: Add new required dependencies to travis
* lang: lang-build: Improve warning message
"referenced" was really meaning that data is being duplicated.
* lang: Respect the language order as defined in config.sh
This correctly splits normal and community-made entries during language
selection.
* lang: More typos in the documentation
* lang: Check for the maximum size of each language
Each table needs to fit within LANG_SIZE_RESERVED
* lang: Properly align _SEC_LANG to page boundaries
... instead of relying on _SEC_LANG_TABLE to calculate the offset
* lang: Build support for dual-language hex files
Detect the printer type by checking the current variant type.
On printers with no xflash (MK2*), generate one hex file for each
additional language file by patching the built-in secondary language
table during the build process
* lang: Mention lang-patchsec.py
* lang: Use color() instead of tput for clarity
* lang: Allow disabling terminal colors with NO_COLOR/TERM=dumb
* lang: Consistent use of redirection in config.sh
* lang: Stricter variant-type check for xflash support
* lang: Output size stats when building double-language hex files
* lang: Respect NO_COLOR in lang-check.py
* lang: Check for repeated/incorrect annotations
Catch errors such as "c=1 c=2"
* lang: Correct MSG_SLIGHT_SKEW/MSG_SEVERE_SKEW annotations
* lang: [it] Improve MSG_*_SKEW translation
* lang: Use INTLHEX instead of OUTHEX_P/S for configuration
We already have OUTHEX which is the compiled firmware.
Use INTLHEX for the final internationalized firmware, which is less
confusing. Also, assume it being a prefix for all generated hex
files, which reduces the number of variables set.
* lang: Move lang_map to lib.io for further use
* lang: lang-check: Accept a firmware map file to suppress unused string warnings
* lang: Use the map file to reduce useless warnings during fw-build
* lang: lang-check: Also suppress unused empty annotations
* lang: Fix MSG_MOVE_CARRIAGE_TO_THE_TOP_Z annotation
Refresh pot file
* lang: lang-check: Do not warn about same-word translations by default
Do not warn when one-word translations such as "No" result in "No" also
in other languages, since this is common in latin languages.
Allow to re-enable the warning with --warn-same
* lang: lang-build: Handle same-source/translation efficiently
* lang: [it] Explicitly add On/Off/Reset/Wizard to suppress warnings
Instead of displaying a warning, supress the warning and explicitly
translate each entry using english (which is the common/acceptable
word in these cases).
* lang: [it] Suppress more warnings
* lang: lang-check: Add intermediate "suggest" warning category
Warnings in the "suggest" category as shown as [S] as based on pure
speculation from the checking tool, such as the translation being
significantly shorter than the original.
As a result, they can be suppressed with --no-suggest
* lang: Return translation status from lang-check
- 0 if the translation only contains suggestions
- 1 if the translation contains warnings or errors
Check for the exit status in fw-build.sh, but do nothing at the moment
except printing a non-fatal error.
* lang: Remove "trim_trailing_whitespace=false" for po files
PO files got cleaned up/rewritten. We can now ensure they stay
consistent.
* lang: [sv] Re-integrate changes from 70c73cb
* lang: [no] Reintegrate changes from @pkg2000
2022-06-16 13:03:30 +00:00
|
|
|
if (ui == 0xffff) return s + 2; //id not assigned, return orig. str.
|
2018-05-22 01:20:03 +00:00
|
|
|
ui = pgm_read_word(((uint16_t*)(((char*)lang_table + 16 + ui*2)))); //read relative offset
|
2018-06-07 22:20:28 +00:00
|
|
|
if (pgm_read_byte(((uint8_t*)((char*)lang_table + ui))) == 0) //read first character
|
|
|
|
return s + 2;//zero length string == not translated, return orig. str.
|
2018-05-27 13:14:04 +00:00
|
|
|
return (const char*)((char*)lang_table + ui); //return calculated pointer
|
|
|
|
}
|
|
|
|
|
2018-06-07 22:20:28 +00:00
|
|
|
uint8_t lang_select(uint8_t lang)
|
2018-05-22 01:20:03 +00:00
|
|
|
{
|
2018-06-07 22:20:28 +00:00
|
|
|
if (lang == LANG_ID_PRI) //primary language
|
2018-05-22 01:20:03 +00:00
|
|
|
{
|
|
|
|
lang_table = 0;
|
2018-06-10 14:04:32 +00:00
|
|
|
lang_selected = lang;
|
2018-06-07 22:20:28 +00:00
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#ifdef XFLASH
|
2018-06-10 14:04:32 +00:00
|
|
|
if (lang_get_code(lang) == lang_get_code(LANG_ID_SEC)) lang = LANG_ID_SEC;
|
2018-06-07 22:20:28 +00:00
|
|
|
if (lang == LANG_ID_SEC) //current secondary language
|
|
|
|
{
|
2018-06-10 14:04:32 +00:00
|
|
|
if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
|
|
|
|
{
|
2018-06-15 18:37:33 +00:00
|
|
|
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
|
|
|
|
{
|
2018-07-23 11:35:38 +00:00
|
|
|
lang_table = (lang_table_t*)(_SEC_LANG_TABLE); // set table pointer
|
2018-06-15 18:37:33 +00:00
|
|
|
lang_selected = lang; // set language id
|
|
|
|
}
|
2018-06-10 14:04:32 +00:00
|
|
|
}
|
2018-05-22 01:20:03 +00:00
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#else //XFLASH
|
2018-06-21 18:57:22 +00:00
|
|
|
if (lang == LANG_ID_SEC)
|
|
|
|
{
|
|
|
|
uint16_t table = _SEC_LANG_TABLE;
|
|
|
|
if (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
|
|
|
|
{
|
|
|
|
if (lang_check(table))
|
|
|
|
if (pgm_read_dword(((uint32_t*)(table + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
|
|
|
|
{
|
2019-03-05 15:27:47 +00:00
|
|
|
lang_table = (lang_table_t*)table; // set table pointer
|
2018-06-21 18:57:22 +00:00
|
|
|
lang_selected = lang; // set language id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#endif //XFLASH
|
2018-06-10 14:04:32 +00:00
|
|
|
if (lang_selected == lang)
|
|
|
|
{
|
|
|
|
eeprom_update_byte((unsigned char*)EEPROM_LANG, lang_selected);
|
|
|
|
return 1;
|
|
|
|
}
|
2018-06-08 00:03:25 +00:00
|
|
|
return 0;
|
2018-05-28 15:14:55 +00:00
|
|
|
}
|
|
|
|
|
2018-06-15 18:37:33 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-05-30 17:29:52 +00:00
|
|
|
uint8_t lang_get_count()
|
2018-05-28 17:41:16 +00:00
|
|
|
{
|
2018-06-18 17:37:20 +00:00
|
|
|
if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff)
|
|
|
|
return 1; //signature not set - only primary language will be available
|
2021-03-05 07:51:23 +00:00
|
|
|
#ifdef XFLASH
|
|
|
|
XFLASH_SPI_ENTER();
|
2018-06-07 23:19:49 +00:00
|
|
|
uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
|
2021-06-08 13:20:23 +00:00
|
|
|
uint32_t addr = LANG_OFFSET;
|
2018-06-07 22:20:28 +00:00
|
|
|
lang_table_header_t header; //table header structure
|
|
|
|
while (1)
|
|
|
|
{
|
2021-03-05 07:51:23 +00:00
|
|
|
xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
2018-06-07 22:20:28 +00:00
|
|
|
if (header.magic != LANG_MAGIC) break; //break if magic not valid
|
|
|
|
addr += header.size; //calc address of next table
|
|
|
|
count++; //inc counter
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#else //XFLASH
|
2018-06-21 18:57:22 +00:00
|
|
|
uint16_t table = _SEC_LANG_TABLE;
|
|
|
|
uint8_t count = 1; //count = 1 (primary)
|
|
|
|
while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
|
|
|
|
{
|
|
|
|
table += pgm_read_word((uint16_t*)(table + 4));
|
|
|
|
count++;
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#endif //XFLASH
|
2018-06-21 18:57:22 +00:00
|
|
|
return count;
|
2018-05-28 17:41:16 +00:00
|
|
|
}
|
|
|
|
|
2018-06-08 23:23:04 +00:00
|
|
|
uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset)
|
2018-05-28 15:14:55 +00:00
|
|
|
{
|
2018-06-08 23:23:04 +00:00
|
|
|
if (lang == LANG_ID_PRI) return 0; //primary lang not supported for this function
|
2021-03-05 07:51:23 +00:00
|
|
|
#ifdef XFLASH
|
2018-06-08 23:23:04 +00:00
|
|
|
if (lang == LANG_ID_SEC)
|
|
|
|
{
|
2018-06-09 17:16:36 +00:00
|
|
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
2018-07-23 11:35:38 +00:00
|
|
|
memcpy_P(header, (lang_table_t*)(_SEC_LANG_TABLE), sizeof(lang_table_header_t)); //read table header from progmem
|
2018-06-08 23:23:04 +00:00
|
|
|
if (offset) *offset = ui;
|
2018-06-15 18:37:33 +00:00
|
|
|
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
|
2018-06-08 23:23:04 +00:00
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
XFLASH_SPI_ENTER();
|
2021-06-08 13:20:23 +00:00
|
|
|
uint32_t addr = LANG_OFFSET;
|
2018-06-08 23:23:04 +00:00
|
|
|
lang--;
|
|
|
|
while (1)
|
|
|
|
{
|
2021-03-05 07:51:23 +00:00
|
|
|
xflash_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash
|
2018-06-08 23:23:04 +00:00
|
|
|
if (header->magic != LANG_MAGIC) break; //break if not valid
|
|
|
|
if (offset) *offset = addr;
|
|
|
|
if (--lang == 0) return 1;
|
|
|
|
addr += header->size; //calc address of next table
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#else //XFLASH
|
2018-06-21 18:57:22 +00:00
|
|
|
if (lang == LANG_ID_SEC)
|
|
|
|
{
|
|
|
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
2019-03-05 15:27:47 +00:00
|
|
|
memcpy_P(header, (lang_table_header_t*)ui, sizeof(lang_table_header_t)); //read table header from progmem
|
2018-06-21 18:57:22 +00:00
|
|
|
if (offset) *offset = ui;
|
|
|
|
return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#endif //XFLASH
|
2018-06-22 23:31:38 +00:00
|
|
|
return 0;
|
2018-06-08 23:23:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t lang_get_code(uint8_t lang)
|
|
|
|
{
|
2018-06-07 22:20:28 +00:00
|
|
|
if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN
|
2021-03-05 07:51:23 +00:00
|
|
|
#ifdef XFLASH
|
2018-06-01 08:47:47 +00:00
|
|
|
if (lang == LANG_ID_SEC)
|
|
|
|
{
|
2018-06-09 17:16:36 +00:00
|
|
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
2018-06-07 22:20:28 +00:00
|
|
|
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
|
2018-06-01 08:47:47 +00:00
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
XFLASH_SPI_ENTER();
|
2021-06-08 13:20:23 +00:00
|
|
|
uint32_t addr = LANG_OFFSET;
|
2018-06-07 22:20:28 +00:00
|
|
|
lang_table_header_t header; //table header structure
|
|
|
|
lang--;
|
|
|
|
while (1)
|
|
|
|
{
|
2021-03-05 07:51:23 +00:00
|
|
|
xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash
|
2018-06-07 22:20:28 +00:00
|
|
|
if (header.magic != LANG_MAGIC) break; //break if not valid
|
|
|
|
if (--lang == 0) return header.code;
|
|
|
|
addr += header.size; //calc address of next table
|
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#else //XFLASH
|
2018-06-22 23:31:38 +00:00
|
|
|
uint16_t table = _SEC_LANG_TABLE;
|
|
|
|
uint8_t count = 1; //count = 1 (primary)
|
|
|
|
while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid
|
2018-06-21 18:57:22 +00:00
|
|
|
{
|
2018-06-22 23:31:38 +00:00
|
|
|
if (count == lang) return pgm_read_word(((uint16_t*)(table + 10))); //read language code
|
|
|
|
table += pgm_read_word((uint16_t*)(table + 4));
|
|
|
|
count++;
|
2018-06-21 18:57:22 +00:00
|
|
|
}
|
2021-03-05 07:51:23 +00:00
|
|
|
#endif //XFLASH
|
2018-06-07 22:20:28 +00:00
|
|
|
return LANG_CODE_XX;
|
2018-06-01 08:47:47 +00:00
|
|
|
}
|
|
|
|
|
2018-06-07 22:20:28 +00:00
|
|
|
const char* lang_get_name_by_code(uint16_t code)
|
2018-06-01 08:47:47 +00:00
|
|
|
{
|
2018-06-07 22:20:28 +00:00
|
|
|
switch (code)
|
2018-06-01 08:47:47 +00:00
|
|
|
{
|
2018-06-07 22:20:28 +00:00
|
|
|
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");
|
2018-09-11 01:43:05 +00:00
|
|
|
case LANG_CODE_FR: return _n("Francais");
|
2018-06-07 22:20:28 +00:00
|
|
|
case LANG_CODE_IT: return _n("Italiano");
|
|
|
|
case LANG_CODE_PL: return _n("Polski");
|
2021-12-20 16:32:35 +00:00
|
|
|
#ifdef COMMUNITY_LANGUAGE_SUPPORT //Community language support
|
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_NL
|
|
|
|
case LANG_CODE_NL: return _n("Nederlands"); //community Dutch contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_NL
|
2021-12-21 13:33:35 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_SV
|
|
|
|
case LANG_CODE_SV: return _n("Svenska"); //community Swedish contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_SV
|
2022-02-22 10:56:01 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_NO
|
|
|
|
case LANG_CODE_NO: return _n("Norsk"); //community Swedish contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_NO
|
2021-12-21 14:15:23 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_DA
|
2021-12-21 14:28:33 +00:00
|
|
|
case LANG_CODE_DA: return _n("Dansk"); //community Danish contribution
|
2021-12-21 14:15:23 +00:00
|
|
|
#endif // COMMUNITY_LANG_GROUP1_DA
|
2022-02-10 18:01:04 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_SK
|
2022-02-11 11:49:41 +00:00
|
|
|
case LANG_CODE_SK: return _n("Slovencina"); //community Slovak contribution
|
2022-02-10 18:01:04 +00:00
|
|
|
#endif // COMMUNITY_LANG_GROUP1_SK
|
2021-12-21 14:24:06 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_SL
|
|
|
|
case LANG_CODE_SL: return _n("Slovenscina"); //community Slovanian contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_SL
|
2021-12-21 14:28:33 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_HU
|
|
|
|
case LANG_CODE_HU: return _n("Magyar"); //community Hungarian contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_HU
|
2021-12-21 14:32:54 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_LB
|
|
|
|
case LANG_CODE_LB: return _n("Letzebuergesch"); //community Luxembourgish contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_LB
|
2021-12-21 14:36:34 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_HR
|
|
|
|
case LANG_CODE_HR: return _n("Hrvatski"); //community Croatian contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_HR
|
2022-08-09 07:19:22 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP2_LT
|
2022-01-03 14:00:45 +00:00
|
|
|
case LANG_CODE_LT: return _n("Lietuviu"); //community Lithuanian contribution
|
2022-08-09 07:19:22 +00:00
|
|
|
#endif // COMMUNITY_LANG_GROUP2_LT
|
2022-01-12 09:09:01 +00:00
|
|
|
#ifdef COMMUNITY_LANG_GROUP1_RO
|
|
|
|
case LANG_CODE_RO: return _n("Romana"); //community Romanian contribution
|
|
|
|
#endif // COMMUNITY_LANG_GROUP1_RO
|
2021-03-01 07:22:43 +00:00
|
|
|
|
|
|
|
//Use the 3 lines below as a template and replace 'QR' and 'New language'
|
2021-12-20 16:32:35 +00:00
|
|
|
//#ifdef COMMUNITY_LANG_GROUP1_QR
|
2021-03-01 07:22:43 +00:00
|
|
|
// case LANG_CODE_QR: return _n("New language"); //community contribution
|
2021-12-20 16:32:35 +00:00
|
|
|
//#endif // COMMUNITY_LANG_GROUP1_QR
|
|
|
|
#endif // COMMUNITY_LANGUAGE_SUPPORT
|
2018-06-01 08:47:47 +00:00
|
|
|
}
|
2018-06-07 22:20:28 +00:00
|
|
|
return _n("??");
|
2018-05-28 15:14:55 +00:00
|
|
|
}
|
|
|
|
|
2018-06-10 14:04:32 +00:00
|
|
|
void lang_reset(void)
|
|
|
|
{
|
|
|
|
lang_selected = 0;
|
|
|
|
eeprom_update_byte((unsigned char*)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t lang_is_selected(void)
|
|
|
|
{
|
|
|
|
uint8_t lang_eeprom = eeprom_read_byte((unsigned char*)EEPROM_LANG);
|
|
|
|
return (lang_eeprom != LANG_ID_FORCE_SELECTION) && (lang_eeprom == lang_selected);
|
|
|
|
}
|
|
|
|
|
2018-05-30 17:29:52 +00:00
|
|
|
#ifdef DEBUG_SEC_LANG
|
2018-10-18 13:39:08 +00:00
|
|
|
#include <stdio.h>
|
2018-06-07 22:20:28 +00:00
|
|
|
const char* lang_get_sec_lang_str_by_id(uint16_t id)
|
|
|
|
{
|
2018-06-09 17:16:36 +00:00
|
|
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
2018-06-07 22:20:28 +00:00
|
|
|
return ui + pgm_read_word(((uint16_t*)(ui + 16 + id * 2))); //read relative offset and return calculated pointer
|
|
|
|
}
|
|
|
|
|
2018-05-30 17:29:52 +00:00
|
|
|
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)));
|
2018-06-01 08:47:47 +00:00
|
|
|
printf_P(_n(" _lt_magic = 0x%08lx %S\n"), _lt_magic, (_lt_magic==LANG_MAGIC)?_n("OK"):_n("NA"));
|
2018-05-30 17:29:52 +00:00
|
|
|
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);
|
2018-06-01 08:47:47 +00:00
|
|
|
if (_lt_magic != LANG_MAGIC) return 0;
|
2018-05-30 17:29:52 +00:00
|
|
|
puts_P(_n(" strings:\n"));
|
2018-06-09 17:16:36 +00:00
|
|
|
uint16_t ui = _SEC_LANG_TABLE; //table pointer
|
2018-05-30 17:29:52 +00:00
|
|
|
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
|
|
|
|
|
2018-06-07 22:20:28 +00:00
|
|
|
#endif //(LANG_MODE == 0)
|
2018-05-30 17:29:52 +00:00
|
|
|
|
2018-05-29 19:03:47 +00:00
|
|
|
|
2018-06-09 22:22:28 +00:00
|
|
|
void lang_boot_update_start(uint8_t lang)
|
2018-06-09 17:16:36 +00:00
|
|
|
{
|
|
|
|
uint8_t cnt = lang_get_count();
|
|
|
|
if ((lang < 2) || (lang > cnt)) return; //only languages from xflash can be selected
|
2022-01-13 14:01:36 +00:00
|
|
|
bootapp_reboot_user0(lang << 3);
|
2018-06-09 17:16:36 +00:00
|
|
|
}
|