This commit is contained in:
2026-03-21 12:44:27 -05:00
parent e26b52bc7e
commit 08997c7109
4 changed files with 41 additions and 9 deletions

View File

@@ -59,8 +59,10 @@
const CAPABILITIES_UUID = 'c5f50003-8280-46da-89f4-6d8051e4aeef';
// Command codes
const CMD_WRITE_USER_PROGRAM_META = 0x06;
const CMD_WRITE_USER_RAM = 0x03;
const CMD_WRITE_USER_PROGRAM_META = 0x06; // ✅ correct
const CMD_WRITE_USER_PROGRAM = 0x07; // writes to FLASH (button runnable)
const CMD_WRITE_USER_RAM = 0x03; // writes to RAM only
const CMD_START_USER_PROGRAM = 0x01; // triggers run immediately
let device, server, cmdChar, maxDataSize = 20;
@@ -125,6 +127,17 @@
}
}
function crc32(buf) {
let crc = 0xFFFFFFFF;
for (let i = 0; i < buf.length; i++) {
crc ^= buf[i];
for (let j = 0; j < 8; j++) {
crc = (crc >>> 1) ^ (crc & 1 ? 0xEDB88320 : 0);
}
}
return (crc ^ 0xFFFFFFFF) >>> 0;
}
async function upload() {
try {
const resp = await fetch('./main.mpy');
@@ -134,23 +147,31 @@
log(`Uploading ${mpy.length} bytes...`);
setStatus('Uploading...');
// Write program metadata: cmd(1) + size(4 LE)
// 1. Metadata
const meta = new Uint8Array(5);
meta[0] = CMD_WRITE_USER_PROGRAM_META;
meta[0] = 0x06; // CMD_WRITE_USER_PROGRAM_META
new DataView(meta.buffer).setUint32(1, mpy.length, true);
await cmdChar.writeValueWithResponse(meta);
// Write program data in chunks: cmd(1) + offset(4 LE) + data
const chunkSize = maxDataSize - 5; // 1 byte cmd + 4 bytes offset
// 2. Flash chunks
const chunkSize = maxDataSize - 5;
for (let offset = 0; offset < mpy.length; offset += chunkSize) {
const chunk = mpy.slice(offset, offset + chunkSize);
const packet = new Uint8Array(5 + chunk.length);
packet[0] = CMD_WRITE_USER_RAM;
packet[0] = 0x07; // CMD_WRITE_USER_PROGRAM (flash)
new DataView(packet.buffer).setUint32(1, offset, true);
packet.set(chunk, 5);
await cmdChar.writeValueWithResponse(packet);
}
// 3. Checksum
const checksum = crc32(mpy);
const cksPacket = new Uint8Array(5);
cksPacket[0] = 0x08; // CMD_WRITE_USER_PROGRAM_CHECKSUM
new DataView(cksPacket.buffer).setUint32(1, checksum, true);
await cmdChar.writeValueWithResponse(cksPacket);
log(`Checksum: 0x${checksum.toString(16)}`);
setStatus('Upload complete');
log('Upload complete. Press the hub button to run.');
} catch (e) {
@@ -158,7 +179,16 @@
log('Error: ' + e.message);
}
}
function onNotify(event) {
const data = new Uint8Array(event.target.value.buffer);
if (data[0] === 0x01) {
log('[stdout] ' + new TextDecoder().decode(data.slice(1)));
} else if (data[0] === 0x00) {
log('[status] Hub status code: ' + data[1]); // 0x00 = idle, etc.
} else {
log('[event 0x' + data[0].toString(16) + '] ' + Array.from(data).join(','));
}
}
async function disconnect() {
if (device && device.gatt.connected) {
device.gatt.disconnect();

BIN
main.mpy Normal file

Binary file not shown.

View File

@@ -1,4 +1,6 @@
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color
from pybricks.tools import wait
hub = PrimeHub()
hub.light.on(Color.GREEN)
hub.light.on(Color.GREEN)
wait(1000)

BIN
main2.mpy Normal file

Binary file not shown.