7 Commits

11 changed files with 97 additions and 26 deletions

View File

@@ -20,7 +20,7 @@ jobs:
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
with: with:
version: 8 version: 9
- name: 🐉 Use Node.js 22.4.x - name: 🐉 Use Node.js 22.4.x
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:

View File

@@ -1,11 +1,11 @@
{ {
"name": "charachorder-device-manager", "name": "charachorder-device-manager",
"version": "2.1.0", "version": "2.2.1",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"private": true, "private": true,
"engines": { "engines": {
"node": ">=18.16", "node": ">=22.4",
"pnpm": ">=8.6" "pnpm": ">=9.4"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "app" name = "app"
version = "2.1.0" version = "2.2.1"
description = "A Tauri App" description = "A Tauri App"
authors = ["Thea Schöbl <dev@theaninova.de>"] authors = ["Thea Schöbl <dev@theaninova.de>"]
license = "AGPL-3" license = "AGPL-3"

View File

@@ -6,7 +6,7 @@
"devPath": "http://localhost:5173", "devPath": "http://localhost:5173",
"distDir": "../build" "distDir": "../build"
}, },
"package": { "productName": "amacc1ng", "version": "2.1.0" }, "package": { "productName": "amacc1ng", "version": "2.2.1" },
"tauri": { "tauri": {
"allowlist": { "all": false }, "allowlist": { "all": false },
"bundle": { "bundle": {

View File

@@ -5,20 +5,33 @@ col:
row: row:
- switch: { e: 26, n: 27, w: 28, s: 29 } - switch: { e: 26, n: 27, w: 28, s: 29 }
- switch: { e: 21, n: 22, w: 23, s: 24 } - switch: { e: 21, n: 22, w: 23, s: 24 }
- offset: [4, 0]
switch: { w: 66, n: 67, e: 68, s: 69 }
- switch: { w: 71, n: 72, e: 73, s: 74 }
- offset: [2, 0] - offset: [2, 0]
row: row:
- switch: { e: 41, n: 42, w: 43, s: 44 } - switch: { e: 41, n: 42, w: 43, s: 44 }
- switch: { e: 36, n: 37, w: 38, s: 39 } - switch: { e: 36, n: 37, w: 38, s: 39 }
- offset: [4, 0]
switch: { w: 81, n: 82, e: 83, s: 84 }
- switch: { w: 86, n: 87, e: 88, s: 89 }
# Pinkie / Index # Pinkie / Index
- offset: [0, -3] - offset: [0, -3]
row: row:
- switch: { e: 31, n: 32, w: 33, s: 34 } - switch: { e: 31, n: 32, w: 33, s: 34 }
- offset: [4, 0] - offset: [4, 0]
switch: { e: 16, n: 17, w: 18, s: 19 } switch: { e: 16, n: 17, w: 18, s: 19 }
- switch: { w: 61, n: 62, e: 63, s: 64 }
- offset: [4, 0]
switch: { w: 76, n: 77, e: 78, s: 79 }
# Thumbs # Thumbs
- row: - row:
- offset: [5.5, 0.5] - offset: [5.5, 0.5]
switch: { e: 11, n: 12, w: 13, s: 14 } switch: { e: 11, n: 12, w: 13, s: 14 }
- offset: [1, 0.5]
switch: { w: 56, n: 57, e: 58, s: 59 }
- row: - row:
- offset: [4.5, -0.25] - offset: [4.5, -0.25]
switch: { e: 6, n: 7, w: 8, s: 9 } switch: { e: 6, n: 7, w: 8, s: 9 }
- offset: [3, -0.25]
switch: { w: 51, n: 52, e: 53, s: 54 }

View File

@@ -1,24 +1,37 @@
name: M4GR name: M4G
col: col:
# Ring / Middle # Ring / Middle
- offset: [2, 0] - offset: [2, 0]
row: row:
- switch: { e: 23, n: 22, w: 21, s: 24 } - switch: { e: 26, n: 27, w: 28, s: 29 }
- switch: { e: 28, n: 27, w: 26, s: 29 } - switch: { e: 21, n: 22, w: 23, s: 24 }
- offset: [4, 0]
switch: { w: 66, n: 67, e: 68, s: 69 }
- switch: { w: 71, n: 72, e: 73, s: 74 }
- offset: [2, 0] - offset: [2, 0]
row: row:
- switch: { e: 38, n: 37, w: 36, s: 39 } - switch: { e: 41, n: 42, w: 43, s: 44 }
- switch: { e: 43, n: 42, w: 41, s: 44 } - switch: { e: 36, n: 37, w: 38, s: 39 }
- offset: [4, 0]
switch: { w: 81, n: 82, e: 83, s: 84 }
- switch: { w: 86, n: 87, e: 88, s: 89 }
# Pinkie / Index # Pinkie / Index
- offset: [0, -3] - offset: [0, -3]
row: row:
- switch: { e: 18, n: 17, w: 16, s: 19 } - switch: { e: 31, n: 32, w: 33, s: 34 }
- offset: [4, 0] - offset: [4, 0]
switch: { e: 33, n: 32, w: 31, s: 34 } switch: { e: 16, n: 17, w: 18, s: 19 }
- switch: { w: 61, n: 62, e: 63, s: 64 }
- offset: [4, 0]
switch: { w: 76, n: 77, e: 78, s: 79 }
# Thumbs # Thumbs
- row: - row:
- offset: [0.5, 0.5] - offset: [5.5, 0.5]
switch: { e: 13, n: 12, w: 11, s: 14 } switch: { e: 11, n: 12, w: 13, s: 14 }
- offset: [1, 0.5]
switch: { w: 56, n: 57, e: 58, s: 59 }
- row: - row:
- offset: [1.5, -0.25] - offset: [4.5, -0.25]
switch: { e: 8, n: 7, w: 6, s: 9 } switch: { e: 6, n: 7, w: 8, s: 9 }
- offset: [3, -0.25]
switch: { w: 51, n: 52, e: 53, s: 54 }

View File

@@ -25,8 +25,8 @@ const KEY_COUNTS = {
TWO: 90, TWO: 90,
LITE: 67, LITE: 67,
X: 256, X: 256,
M4G: 64, M4G: 90,
M4GR: 64, M4GR: 90,
} as const; } as const;
if ( if (

View File

@@ -113,8 +113,9 @@
const { Transport, ESPLoader } = await import("esptool-js"); const { Transport, ESPLoader } = await import("esptool-js");
const espLoader = new ESPLoader({ const espLoader = new ESPLoader({
transport: new Transport(port), transport: new Transport(port),
baudrate: Number(esptool.baud), baudrate: 9600, // Number(esptool.baud),
romBaudrate: Number(esptool.baud), romBaudrate: 9600, // Number(esptool.baud),
debugLogging: true,
terminal: { terminal: {
clean: () => { clean: () => {
terminalOutput = ""; terminalOutput = "";
@@ -127,8 +128,10 @@
}, },
}, },
} satisfies LoaderOptions); } satisfies LoaderOptions);
await espLoader.connect(esptool.before); await espLoader.detectChip(esptool.before);
await espLoader.runStub(); if (!espLoader.IS_STUB) {
await espLoader.runStub();
}
return espLoader; return espLoader;
} }
@@ -162,6 +165,25 @@
port.close(); port.close();
} }
} }
async function eraseSPI() {
const port = await navigator.serial.requestPort();
try {
console.log(data.meta);
const spiFlash = data.meta.spi_flash!;
espLoader = await connectEsp(port);
/*espLoader.flashSpiAttach(
(spiFlash.connection.clk << 0) |
(spiFlash.connection.q << 8) |
(spiFlash.connection.d << 16) |
(spiFlash.connection.cs << 24),
);
espLoader.flashId();*/
} finally {
port.close();
}
}
</script> </script>
<div class="container"> <div class="container">
@@ -268,7 +290,7 @@
{#if data.meta.update.esptool} {#if data.meta.update.esptool}
<section> <section>
<h3>Factory Flash</h3> <h3>Factory Flash (WIP)</h3>
<p> <p>
If everything else fails, you can go through the same process that is If everything else fails, you can go through the same process that is
being used in the factory. being used in the factory.
@@ -288,6 +310,9 @@
<label <label
><input type="checkbox" id="erase" bind:checked={eraseAll} />Erase All</label ><input type="checkbox" id="erase" bind:checked={eraseAll} />Erase All</label
> >
<button onclick={eraseSPI}
><span class="icon">developer_board</span>Erase SPI Flash</button
>
</div> </div>
<pre>{terminalOutput}</pre> <pre>{terminalOutput}</pre>

View File

@@ -44,6 +44,7 @@ export const load = (async ({ fetch, params }) => {
(entry) => (entry) =>
entry.type === "file" && (!meta?.files || entry.name in meta.files), entry.type === "file" && (!meta?.files || entry.name in meta.files),
) as FileListing[], ) as FileListing[],
spi_flash: meta?.spi_flash ?? undefined,
}, },
}; };
}) satisfies PageLoad; }) satisfies PageLoad;

View File

@@ -12,6 +12,21 @@ export interface VersionMeta {
esptool: EspToolData | null; esptool: EspToolData | null;
}; };
files: string[]; files: string[];
spi_flash: SPIFlashInfo | null;
}
export interface SPIFlashInfo {
type: string;
size: string;
connection: SPIConnection;
}
export interface SPIConnection {
clk: number;
q: number;
d: number;
hd: number;
cs: number;
} }
export interface EspToolData { export interface EspToolData {

View File

@@ -43,7 +43,7 @@
buildIndex($chords, $osLayout).then(searchIndex.set); buildIndex($chords, $osLayout).then(searchIndex.set);
}); });
function encodeChord(chord: ChordInfo, osLayout: Map<string, string>) { function encodeChord(chord: ChordInfo, osLayout: Map<string, string>, onlyPhrase: boolean = false) {
const plainPhrase: string[] = [""]; const plainPhrase: string[] = [""];
const extraActions: string[] = []; const extraActions: string[] = [];
const extraCodes: string[] = []; const extraCodes: string[] = [];
@@ -103,6 +103,10 @@
return result ?? `0x${it.toString(16)}`; return result ?? `0x${it.toString(16)}`;
}); });
if (onlyPhrase) {
return plainPhrase.join();
}
return [ return [
...plainPhrase, ...plainPhrase,
`+${input.join("+")}`, `+${input.join("+")}`,
@@ -182,7 +186,7 @@
function downloadVocabulary() { function downloadVocabulary() {
const vocabulary = new Set( const vocabulary = new Set(
$chords.map((it) => $chords.map((it) =>
"phrase" in it ? plainPhrase(it.phrase, $osLayout).trim() : "", "phrase" in it ? encodeChord(it, $osLayout, true).trim() : "",
), ),
); );
vocabulary.delete(""); vocabulary.delete("");