blitflash
Version:
A JavaScript implementation of the 32blit flash tools
134 lines (133 loc) • 5.53 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BlitConnection = void 0;
const BlitMeta_1 = require("./BlitMeta");
const ReadBuffer_1 = require("./ReadBuffer");
class BlitConnection {
constructor(reader, writer, options = { debug: false }) {
this.reader = reader;
this.writer = writer;
this.options = options;
this.debug = false;
this.encoder = new TextEncoder();
this.decoder = new TextDecoder();
this.readBuffer = new ReadBuffer_1.ReadBuffer();
this.readLoop();
}
readLoop() {
return __awaiter(this, void 0, void 0, function* () {
while (true) {
const { value, done } = yield this.reader.read();
if (value) {
if (this.options.debug) {
console.log('>>>', this.decoder.decode(value));
}
this.readBuffer.append(value);
}
if (done) {
this.reader.releaseLock();
this.readBuffer.failPendingPromises(new Error('ReadableStream is done.'));
break;
}
}
});
}
write(payload) {
return __awaiter(this, void 0, void 0, function* () {
const encoded = this.encoder.encode(payload);
yield this.writer.write(encoded);
});
}
close() {
return __awaiter(this, void 0, void 0, function* () {
yield this.writer.close();
yield this.reader.cancel();
});
}
reset() {
return __awaiter(this, void 0, void 0, function* () {
yield this.write('32BL_RST\0');
yield this.writer.ready;
});
}
status() {
return __awaiter(this, void 0, void 0, function* () {
yield this.write('32BLINFO\0');
const result = yield this.readBuffer.read(8);
return this.decoder.decode(result);
});
}
list() {
return __awaiter(this, void 0, void 0, function* () {
const records = [];
yield this.write('32BL__LS\0');
let offset = yield this.readBuffer.readUint32(true);
while (offset !== 0xFFFFFFFF) {
let size = yield this.readBuffer.readUint32(true);
const metaHead = this.decoder.decode(yield this.readBuffer.read(8));
if (metaHead !== 'BLITMETA') {
throw new Error(`Incorret meta header. Received ${metaHead}`);
}
const metaSize = yield this.readBuffer.readUint16(true);
let meta;
if (metaSize > 0) {
size = size + metaSize + 10;
meta = BlitMeta_1.BlitMetaStandalone.parse((yield this.readBuffer.read(metaSize)).buffer);
}
records.push({
offset: offset,
size: size,
meta: meta,
});
offset = yield this.readBuffer.readUint32(true);
}
return records;
});
}
sendFile(data, drive, filename, directory = '') {
return __awaiter(this, void 0, void 0, function* () {
const filesize = data.byteLength;
const chunkSize = 1024;
let command;
if (drive === 'sd') {
if (this.options.debug) {
console.log(`Saving ${filename} (${filesize} bytes) as in ${directory}.`);
}
command = `32BLSAVE${directory}/${filename}\x00${filesize}\x00`;
}
else {
if (this.options.debug) {
console.log(`Flashing ${filename} (${filesize} bytes)`);
}
command = `32BLPROG${filename}\x00${filesize}\x00`;
}
yield this.write(command);
let written = 0;
const stream = new Uint8Array(data);
while (written < filesize) {
yield this.writer.ready;
const end = Math.min(written + chunkSize, filesize);
this.writer.write(stream.slice(written, end));
written = end;
}
yield this.writer.ready;
if (this.options.debug) {
console.log(`Wrote ${data.byteLength} bytes`);
}
const response = yield this.readBuffer.readString(8);
if (response !== '32BL__OK') {
throw new Error(`Failed to send file with result ${response}.`);
}
});
}
}
exports.BlitConnection = BlitConnection;