Phase 4: user dict, console commands, undo wiring
- engine_init.cc: user dict (16KB RAM-backed) added to dict stack as highest priority. Console commands registered (list/enable/disable/ toggle dicts, lookup, add/remove translations, template values). Undo stroke (*) already handled by StenoEngine::Process(). - zmk_console_shim.cc: route Javelin console output to ZMK logging (line-buffered, LOG_INF per line). Enables debug visibility. All Phase 4 features (undo, user dict, add_translation mode, console mode, orthography engine, all processor types) are already compiled from Javelin source — this commit wires them into the init path. Orthography rules: empty for now (suffix folding disabled). Full orthography requires separate data in the binary — planned for dict compiler enhancement.
This commit is contained in:
parent
580d2ed5b8
commit
1d450a5dd1
2 changed files with 63 additions and 16 deletions
|
|
@ -1,10 +1,12 @@
|
|||
#include "zmk_javelin_steno/zmk_platform_shim.h"
|
||||
|
||||
#include "console.h"
|
||||
#include "container/list.h"
|
||||
#include "dictionary/dictionary_definition.h"
|
||||
#include "dictionary/dictionary_list.h"
|
||||
#include "dictionary/user_dictionary.h"
|
||||
#include "engine.h"
|
||||
#include "flash.h"
|
||||
#include "orthography.h"
|
||||
#include "processor/all_up.h"
|
||||
#include "processor/first_up.h"
|
||||
|
|
@ -22,13 +24,19 @@ extern "C" {
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
// Linker symbols for the embedded dictionary binary.
|
||||
// Defined by the linker script or incbin directive in dict_embed.S
|
||||
// Linker symbols for embedded dictionary binary (dict_embed.S)
|
||||
extern "C" const uint8_t _javelin_dict_start[];
|
||||
extern "C" const uint8_t _javelin_dict_end[];
|
||||
|
||||
// User dictionary flash region.
|
||||
// Must be power-of-2 sized. 16KB = 2^14.
|
||||
// In production, this points to a dedicated flash partition.
|
||||
// For now, use a RAM buffer as placeholder until flash partition is configured.
|
||||
static uint8_t user_dict_mem[16384] __attribute__((aligned(4)));
|
||||
|
||||
static JavelinStaticAllocate<StenoCompiledOrthography> compiledOrthography;
|
||||
static JavelinStaticAllocate<StenoDictionaryList> dictionaryList;
|
||||
static JavelinStaticAllocate<StenoUserDictionary> userDictionary;
|
||||
static JavelinStaticAllocate<StenoJeffModifiers> jeffModifiers;
|
||||
static JavelinStaticAllocate<StenoRepeat> stenoRepeat;
|
||||
static JavelinStaticAllocate<StenoAllUp> allUp;
|
||||
|
|
@ -47,29 +55,46 @@ static bool load_dictionary_collection() {
|
|||
}
|
||||
|
||||
if (!collection->HasMatchingTimestamp()) {
|
||||
LOG_ERR("Steno dict timestamp mismatch — incomplete upload?");
|
||||
LOG_ERR("Steno dict timestamp mismatch");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load dictionaries from collection
|
||||
List<StenoDictionaryListEntry> entries;
|
||||
collection->AddDictionariesToList(entries);
|
||||
|
||||
if (entries.IsEmpty()) {
|
||||
LOG_ERR("Steno dict collection has no dictionaries");
|
||||
LOG_ERR("Steno dict collection empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
new (dictionaryList) StenoDictionaryList(static_cast<List<StenoDictionaryListEntry>&&>(entries));
|
||||
// Set up user dictionary (RAM-backed for now, flash-backed in future)
|
||||
StenoUserDictionaryData userDictData(user_dict_mem, sizeof(user_dict_mem));
|
||||
new (userDictionary) StenoUserDictionary(userDictData);
|
||||
|
||||
// Add user dict as highest priority (first in list)
|
||||
entries.Insert(0, StenoDictionaryListEntry(&userDictionary.value, true));
|
||||
|
||||
new (dictionaryList)
|
||||
StenoDictionaryList(static_cast<List<StenoDictionaryListEntry> &&>(entries));
|
||||
|
||||
// Load orthography from collection if present, else empty
|
||||
const StenoOrthography *ortho = &StenoOrthography::emptyOrthography;
|
||||
// TODO: load orthography from collection if present
|
||||
new (compiledOrthography) StenoCompiledOrthography(*ortho);
|
||||
|
||||
new (StenoEngine::container)
|
||||
StenoEngine(dictionaryList.value, nullptr, compiledOrthography.value);
|
||||
// Construct engine with full dict stack + user dict
|
||||
new (StenoEngine::container) StenoEngine(
|
||||
dictionaryList.value,
|
||||
nullptr,
|
||||
compiledOrthography.value,
|
||||
StenoStroke(StrokeMask::STAR), // undo stroke = *
|
||||
&userDictionary.value);
|
||||
|
||||
LOG_INF("Steno engine initialized with %d dictionaries",
|
||||
collection->dictionaryCount);
|
||||
// Register console commands
|
||||
StenoEngine::container.value.AddConsoleCommands(Console::instance);
|
||||
Flash::AddConsoleCommands(Console::instance);
|
||||
|
||||
LOG_INF("Steno engine: %d dicts + user dict", collection->dictionaryCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -81,12 +106,15 @@ void zmk_javelin_steno_init(void) {
|
|||
}
|
||||
initialized = true;
|
||||
|
||||
// Initialize user dict memory to erased state (0xFF)
|
||||
memset(user_dict_mem, 0xFF, sizeof(user_dict_mem));
|
||||
|
||||
if (!load_dictionary_collection()) {
|
||||
LOG_WRN("Steno engine not started — no valid dictionary found");
|
||||
LOG_WRN("Steno engine not started");
|
||||
return;
|
||||
}
|
||||
|
||||
// Build processor pipeline: Repeat → AllUp → JeffModifiers → Engine
|
||||
// Processor pipeline: Repeat → AllUp → JeffModifiers → Engine
|
||||
new (jeffModifiers) StenoJeffModifiers(StenoEngine::container.value);
|
||||
new (allUp) StenoAllUp(jeffModifiers.value);
|
||||
new (stenoRepeat) StenoRepeat(allUp.value);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,28 @@
|
|||
#include "console.h"
|
||||
|
||||
// ConsoleWriter::Write is the main output path for Javelin's console system.
|
||||
// For Phase 1, stub it out. Phase 4 will route to USB CDC or ZMK logging.
|
||||
extern "C" {
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
}
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
// Route Javelin console output to ZMK logging system.
|
||||
// In Phase 5, this can be upgraded to USB CDC ACM for interactive console.
|
||||
|
||||
static char line_buf[256];
|
||||
static size_t line_pos = 0;
|
||||
|
||||
void ConsoleWriter::Write(const char *data, size_t length) {
|
||||
(void)data;
|
||||
(void)length;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (data[i] == '\n' || line_pos >= sizeof(line_buf) - 1) {
|
||||
line_buf[line_pos] = '\0';
|
||||
if (line_pos > 0) {
|
||||
LOG_INF("[steno] %s", line_buf);
|
||||
}
|
||||
line_pos = 0;
|
||||
} else {
|
||||
line_buf[line_pos++] = data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue