diff --git a/main.html b/main.html index 4f2972e..dadac68 100644 --- a/main.html +++ b/main.html @@ -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(); diff --git a/main.mpy b/main.mpy new file mode 100644 index 0000000..a54675f Binary files /dev/null and b/main.mpy differ diff --git a/main.py b/main.py index d19b432..ede11d0 100644 --- a/main.py +++ b/main.py @@ -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) \ No newline at end of file +hub.light.on(Color.GREEN) +wait(1000) \ No newline at end of file diff --git a/main2.mpy b/main2.mpy new file mode 100644 index 0000000..5cb11f6 Binary files /dev/null and b/main2.mpy differ