Test
This commit is contained in:
46
main.html
46
main.html
@@ -59,8 +59,10 @@
|
|||||||
const CAPABILITIES_UUID = 'c5f50003-8280-46da-89f4-6d8051e4aeef';
|
const CAPABILITIES_UUID = 'c5f50003-8280-46da-89f4-6d8051e4aeef';
|
||||||
|
|
||||||
// Command codes
|
// Command codes
|
||||||
const CMD_WRITE_USER_PROGRAM_META = 0x06;
|
const CMD_WRITE_USER_PROGRAM_META = 0x06; // ✅ correct
|
||||||
const CMD_WRITE_USER_RAM = 0x03;
|
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;
|
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() {
|
async function upload() {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch('./main.mpy');
|
const resp = await fetch('./main.mpy');
|
||||||
@@ -134,23 +147,31 @@
|
|||||||
log(`Uploading ${mpy.length} bytes...`);
|
log(`Uploading ${mpy.length} bytes...`);
|
||||||
setStatus('Uploading...');
|
setStatus('Uploading...');
|
||||||
|
|
||||||
// Write program metadata: cmd(1) + size(4 LE)
|
// 1. Metadata
|
||||||
const meta = new Uint8Array(5);
|
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);
|
new DataView(meta.buffer).setUint32(1, mpy.length, true);
|
||||||
await cmdChar.writeValueWithResponse(meta);
|
await cmdChar.writeValueWithResponse(meta);
|
||||||
|
|
||||||
// Write program data in chunks: cmd(1) + offset(4 LE) + data
|
// 2. Flash chunks
|
||||||
const chunkSize = maxDataSize - 5; // 1 byte cmd + 4 bytes offset
|
const chunkSize = maxDataSize - 5;
|
||||||
for (let offset = 0; offset < mpy.length; offset += chunkSize) {
|
for (let offset = 0; offset < mpy.length; offset += chunkSize) {
|
||||||
const chunk = mpy.slice(offset, offset + chunkSize);
|
const chunk = mpy.slice(offset, offset + chunkSize);
|
||||||
const packet = new Uint8Array(5 + chunk.length);
|
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);
|
new DataView(packet.buffer).setUint32(1, offset, true);
|
||||||
packet.set(chunk, 5);
|
packet.set(chunk, 5);
|
||||||
await cmdChar.writeValueWithResponse(packet);
|
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');
|
setStatus('Upload complete');
|
||||||
log('Upload complete. Press the hub button to run.');
|
log('Upload complete. Press the hub button to run.');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -158,7 +179,16 @@
|
|||||||
log('Error: ' + e.message);
|
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() {
|
async function disconnect() {
|
||||||
if (device && device.gatt.connected) {
|
if (device && device.gatt.connected) {
|
||||||
device.gatt.disconnect();
|
device.gatt.disconnect();
|
||||||
|
|||||||
4
main.py
4
main.py
@@ -1,4 +1,6 @@
|
|||||||
from pybricks.hubs import PrimeHub
|
from pybricks.hubs import PrimeHub
|
||||||
from pybricks.parameters import Color
|
from pybricks.parameters import Color
|
||||||
|
from pybricks.tools import wait
|
||||||
hub = PrimeHub()
|
hub = PrimeHub()
|
||||||
hub.light.on(Color.GREEN)
|
hub.light.on(Color.GREEN)
|
||||||
|
wait(1000)
|
||||||
Reference in New Issue
Block a user