dc/hbj11: init with flasher
This brings in the flashing infrastructure for HBJ11 (bluepill&web).
Change-Id: I480855689f849c24712d58a0ccbce6e91c34f8bd
diff --git a/dc/hbj11/flasher/web/i2c.js b/dc/hbj11/flasher/web/i2c.js
new file mode 100644
index 0000000..6aa4ed7
--- /dev/null
+++ b/dc/hbj11/flasher/web/i2c.js
@@ -0,0 +1,159 @@
+/**
+ * Low-level interface to programmer's I2C USB class.
+ *
+ * See //dc/hbj11/flasher/bluepill/src/i2c.rs for more information.
+ */
+
+const ControlInRequest = Object.freeze({
+ 'GetStatus': 1,
+});
+
+const ControlOutRequest = Object.freeze({
+ 'SetLED': 1,
+ 'ReadI2C': 2,
+ 'ReadBuffer': 3,
+ 'WriteI2C': 4,
+ 'SetWritePointer': 5,
+});
+
+export const Status = Object.freeze({
+ 'Idle': 0,
+ 'InvalidArgument': 1,
+ 'Ack': 2,
+ 'Nack': 3,
+ 'BusError': 4,
+});
+
+export const StatusFromU8 = function(u8) {
+ for (const label of Object.keys(Status)) {
+ let val = Status[label];
+ if (val === u8) {
+ return label;
+ }
+ }
+};
+
+/**
+ * Low-level interface to programmer's I2C USB class. Thinly wraps available
+ * USB transfers.
+ */
+export class USBI2CClassInterface {
+ /**
+ * @param {USBDevice} usb - The WebUSB device that backs this USB class.
+ */
+ constructor(device) {
+ this.usb = device;
+ this.BUFFER_SIZE = 1024;
+ this.PACKET_SIZE = 64;
+ }
+
+ /**
+ * Open this programmer via WebUSB and finds all required endpoints.
+ */
+ async open() {
+ await this.usb.open();
+ await this.usb.selectConfiguration(1);
+ await this.usb.claimInterface(0);
+
+ let eps = this.usb.configuration.interfaces[0].alternate.endpoints;
+ this.bulk_out = null;
+ this.bulk_in = null;
+ for (const ep of eps) {
+ if (ep.direction == "out" && ep.type == "bulk") {
+ this.bulk_out = ep;
+ }
+ if (ep.direction == "in" && ep.type == "bulk") {
+ this.bulk_in = ep;
+ }
+ }
+ if (this.bulk_out === null) {
+ throw new Error("Could not find bulk out endpoint");
+ }
+ if (this.bulk_in === null) {
+ throw new Error("Could not find bulk in endpoint");
+ }
+ }
+
+ /**
+ * Performs a USB Control OUT request to the I2C class.
+ * @param {number} request - Request number for transfer (0-255).
+ * @param {number} value - Value for transfer (0-65535).
+ * @returns {Promise<USBOutTransferResult>} The underlying WebUSB transfer result.
+ */
+ async controlOut(request, value) {
+ return await this.usb.controlTransferOut({
+ requestType: "vendor",
+ recipient: "interface",
+ request: request,
+ value: value,
+ index: 0,
+ });
+ }
+
+ /**
+ * Read status from programmer.
+ * @returns {Status} The status of the programmer.
+ */
+ async getStatus() {
+ let res = await this.usb.controlTransferIn({
+ requestType: "vendor",
+ recipient: "interface",
+ request: ControlInRequest.GetStatus,
+ value: 0,
+ index: 0
+ }, 1);
+ if (res.data.byteLength < 1) {
+ throw new Error('returned data too short')
+ }
+ return res.data.getInt8(0);
+ }
+
+ /**
+ * Sends SetLED control OUT request.
+ */
+ async setLED(on) {
+ return await this.controlOut(ControlOutRequest.SetLED, on ? 1 : 0);
+ }
+
+ /**
+ * Sends ReadI2C control OUT request.
+ */
+ async readI2C(addr, length) {
+ return await this.controlOut(ControlOutRequest.ReadI2C, (length << 8) | addr);
+ }
+
+ /**
+ * Sends ReadBuffer control OUT request.
+ */
+ async readBuffer(addr, length) {
+ return await this.controlOut(ControlOutRequest.ReadBuffer, (length << 8) | addr);
+ }
+
+ /**
+ * Sends WriteI2C control OUT request.
+ */
+ async writeI2C(addr, length) {
+ return await this.controlOut(ControlOutRequest.WriteI2C, (length << 8) | addr);
+ }
+
+ /**
+ * Sends SetWritePointer control OUT request.
+ */
+ async setWritePointer(addr) {
+ return await this.controlOut(ControlOutRequest.SetWritePointer, addr);
+ }
+
+ /**
+ * Requets bulk IN data.
+ */
+ async bulkIn(length) {
+ return await this.usb.transferIn(this.bulk_in.endpointNumber, length);
+ }
+
+ /**
+ * Sends bulk OUT data.
+ */
+ async bulkOut(data) {
+ return await this.usb.transferOut(this.bulk_out.endpointNumber, data);
+ }
+}