11 Commits

Author SHA1 Message Date
a3bf9ac32b 2.2.3 2025-01-15 11:31:47 +01:00
David Villafaña
5bd3245084 fix: typographical error (#156)
Co-authored-by: David Rog Desktop <dvillafanaiv@proton.me>
2025-01-15 11:30:46 +01:00
1cd2ec318a 2.2.2 2025-01-14 13:35:53 +01:00
6c8bfa0272 fix: ota update 2025-01-14 13:31:22 +01:00
f69be14b5e 2.2.1 2025-01-06 19:34:28 +01:00
dce554fc66 fix: set pnpm version in github actions correctly 2025-01-06 19:32:43 +01:00
f152dbdcf5 fix: set node/pnpm versions correctly 2025-01-06 19:31:04 +01:00
6a29e6a2fc 2.2.0 2025-01-06 19:25:45 +01:00
9bf3801fef Mark factory flash as wip 2025-01-06 19:25:27 +01:00
d2accfb838 Squash merge fix-vocabulary-export into master 2024-12-09 18:41:26 +01:00
b8a376b93b feat: update m4g 2024-12-09 18:35:05 +01:00
12 changed files with 99 additions and 28 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.3",
"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.3"
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.3" },
"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

@@ -13,7 +13,7 @@
"GTM stands for Generative Text Menu and can be used to change your device's settings anywhere", "GTM stands for Generative Text Menu and can be used to change your device's settings anywhere",
"Ambidextrous Throwover (aka Mirror Mode) is a mode designed for one-handed use", "Ambidextrous Throwover (aka Mirror Mode) is a mode designed for one-handed use",
"Chentry stands for character entry, or typing letter by letter on a chording enabled device", "Chentry stands for character entry, or typing letter by letter on a chording enabled device",
"Chord modifiers are hard-coded (as of now) and can be used in the English language to add conjucations and more", "Chord modifiers are hard-coded (as of now) and can be used in the English language to add conjugations and more",
"You can use 'cursor warping' by adding arrow key actions to a chord, for example to chord '()' with the cursor in the middle of the brackets", "You can use 'cursor warping' by adding arrow key actions to a chord, for example to chord '()' with the cursor in the middle of the brackets",
"An arpeggiate is a single key press that modifies the preceding chord. Modifiers can be arpeggiated", "An arpeggiate is a single key press that modifies the preceding chord. Modifiers can be arpeggiated",
"Some actions are marked as a 'macro', which means the output is generated by a key sequence rather than a pure key press. Be cautious with those, as they can affect other keys when held together!", "Some actions are marked as a 'macro', which means the output is generated by a key sequence rather than a pure key press. Be cautious with those, as they can affect other keys when held together!",

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

@@ -25,7 +25,7 @@
$serialPort = undefined; $serialPort = undefined;
try { try {
const file = await fetch( const file = await fetch(
`${data.meta.path}/${data.meta.update.ota!}`, `${data.meta.path}/${data.meta.update.ota?.name}`,
).then((it) => it.blob()); ).then((it) => it.blob());
await port.updateFirmware(file); await port.updateFirmware(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("");