Add multiple TPU/CPU models Change-Id: I4182961367e090b507f7e04850d12901a303bcf6
diff --git a/Makefile b/Makefile index bd21562..9729a88 100644 --- a/Makefile +++ b/Makefile
@@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. MAKEFILE_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +TEST_DATA_URL := https://github.com/google-coral/edgetpu/raw/master/test_data .PHONY: wasm download zip server dfu-util @@ -48,11 +49,15 @@ "$(MAKEFILE_DIR)/bazel-bin/tflite/interpreter-wasm/interpreter.worker.js" \ "$(MAKEFILE_DIR)/site" -download: - cd $(MAKEFILE_DIR)/site && \ - rm -f *.tflite* && \ - wget https://github.com/google-coral/test_data/raw/master/mobilenet_v1_1.0_224_quant.tflite \ - https://github.com/google-coral/test_data/raw/master/mobilenet_v1_1.0_224_quant_edgetpu.tflite +%.tflite: + cd $(dir $@) && wget "$(TEST_DATA_URL)/$(notdir $@)" + +download: site/mobilenet_v1_1.0_224_quant.tflite \ + site/mobilenet_v1_1.0_224_quant_edgetpu.tflite \ + site/ssd_mobilenet_v2_coco_quant_postprocess.tflite \ + site/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite \ + site/ssd_mobilenet_v2_face_quant_postprocess.tflite \ + site/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite dfu-util: git clone git://git.code.sf.net/p/dfu-util/dfu-util || true
diff --git a/README.md b/README.md index a7bd081..558a81a 100644 --- a/README.md +++ b/README.md
@@ -1,4 +1,8 @@ # WebCoral -emscripten_toolchain is copied from +Firmware upload is done via webdfu + +emscripten_toolchain for Bazel is taken from https://github.com/emscripten-core/emsdk/tree/master/bazel/emscripten_toolchain + +libusb.cc -- universal shim, inspired by
diff --git a/site/index.html b/site/index.html index fba98ca..e8aa5a2 100644 --- a/site/index.html +++ b/site/index.html
@@ -5,23 +5,64 @@ <title>Coral USB Accelerator Demo</title> <script src="dfu.js"></script> <script src="dfuse.js"></script> - <script src="imagenet_labels.js"></script> + <script src="labels.js"></script> <script src="tflite.js"></script> <script src="interpreter.js"></script> </head> <body> <h1>Coral USB Accelerator Demo</h1> <button id="button-firmware">1. Flash Device Firmware</button> <span id="firmware-status"></span><br/><br/> - <button id="button-init">2. Initialize Device</button><input type="checkbox" id="cpu-model">CPU</input><br/><br/> + <button id="button-init">2. Initialize Device</button> + <select id="model"> + <option value="mobilenet_cpu">MobileNet V1 (CPU)</option> + <option value="mobilenet_tpu">MobileNet V1 (TPU)</option> + <option value="ssd_mobilenet_coco_cpu">SSD MobileNet V2 - Coco (CPU)</option> + <option value="ssd_mobilenet_coco_tpu">SSD MobileNet V2 - Coco (TPU)</option> + <option value="ssd_mobilenet_face_cpu">SSD MobileNet V2 - Face (CPU)</option> + <option value="ssd_mobilenet_face_tpu">SSD MobileNet V2 - Face (TPU)</option> + </select><br/><br/> <button id="button-image" onclick="document.getElementById('file').click();" disabled>3. Choose Image File</button><br/><br/> <input type="file" id="file" style="display:none;"/><br/> - <canvas id="canvas"></canvas> <h2 id="result"></h2> + <canvas id="canvas"></canvas> <br/><br/> <!--button id="test">Inference Test</button><br/><br/--> <script> + const models = { + 'mobilenet_cpu': { + 'url': '/mobilenet_v1_1.0_224_quant.tflite', + 'type': 'classification', + 'labels': imagenet_labels, + }, + 'mobilenet_tpu': { + 'url': '/mobilenet_v1_1.0_224_quant_edgetpu.tflite', + 'type': 'classification', + 'labels': imagenet_labels, + }, + 'ssd_mobilenet_coco_cpu': { + 'url': '/ssd_mobilenet_v2_coco_quant_postprocess.tflite', + 'type': 'detection', + 'labels': coco_labels, + }, + 'ssd_mobilenet_coco_tpu': { + 'url': '/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite', + 'type': 'detection', + 'labels': coco_labels, + }, + 'ssd_mobilenet_face_cpu': { + 'url': '/ssd_mobilenet_v2_face_quant_postprocess.tflite', + 'type': 'detection', + 'labels': ['face'], + }, + 'ssd_mobilenet_face_tpu': { + 'url': '/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite', + 'type': 'detection', + 'labels': ['face'], + }, + }; + async function loadLocalImage(file) { return new Promise(resolve => { var reader = new FileReader(); @@ -145,49 +186,80 @@ } let interpreter; + let model; document.querySelector("#button-init").addEventListener('click', async () => { - let modelName = '/mobilenet_v1_1.0_224_quant_edgetpu.tflite'; - if (document.getElementById("cpu-model").checked) - modelName = '/mobilenet_v1_1.0_224_quant.tflite'; - - let model = new Uint8Array(await loadFile(modelName)); - let modelBufferSize = model.length * model.BYTES_PER_ELEMENT; - let modelBuffer = Module._malloc(modelBufferSize); - Module.HEAPU8.set(model, modelBuffer); - + model = models[document.getElementById('model').value]; + console.log(model); interpreter = new tflite.Interpreter(); - if (await interpreter.create(modelBuffer, modelBufferSize)) { + if (await interpreter.createFromBuffer(await loadFile(model.url))) { document.getElementById("button-firmware").disabled = true; document.getElementById("button-init").disabled = true; - document.getElementById("cpu-model").disabled = true; + document.getElementById("model").disabled = true; document.getElementById("button-image").disabled = false; } }); document.querySelector("#file").addEventListener('change', async () => { - var input = document.getElementById("file"); - var file = input.files[0]; + const input = document.getElementById("file"); + const file = input.files[0]; if (!file) return; - [_depth, height, width, _channels] = interpreter.inputShape(); + [_, height, width, _] = interpreter.inputShape(0); + console.log('SHAPE:', width, 'x', height); - let img = await loadLocalImage(file); - var c = document.getElementById("canvas"); + const img = await loadLocalImage(file); + const c = document.getElementById("canvas"); c.width = width; c.height = height; - var ctx = c.getContext('2d'); - ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height); + const ctx = c.getContext('2d'); + const color = 'red'; + ctx.strokeStyle = color; + ctx.fillStyle = color; + ctx.textBaseline = 'top'; - var imageData = ctx.getImageData(0, 0, width, height); - interpreter.setRgbaInput(0, imageData.data); + switch (model.type) { + case 'classification': + ctx.drawImage(img, 0, 0, img.width, img.height, + 0, 0, width, height); + break; + case 'detection': + const alpha = Math.min(width / img.width, height / img.height); + ctx.drawImage(img, 0, 0, img.width, img.height, + 0, 0, alpha * img.width, alpha * img.height); + break; + } + + const imageData = ctx.getImageData(0, 0, width, height); + tflite.setRgbaInput(interpreter, imageData.data); document.getElementById("result").textContent = "Recognizing..."; - let inference_start = Date.now(); - interpreter.invoke(() => { - let inference_time = Date.now() - inference_start; - let maxIndex = interpreter.getClassificationOutput(0); - document.getElementById("result").textContent = `${imagenet_labels[maxIndex]} (${inference_time} ms)`; - }); + const inferenceStart = Date.now(); + await interpreter.invoke(); + const inferenceTime = Date.now() - inferenceStart; + + let label = null; + switch (model.type) { + case 'classification': + const maxIndex = tflite.getClassificationOutput(interpreter); + console.log('Class:', maxIndex); + label = model.labels[maxIndex]; + break; + case 'detection': + const objects = tflite.getDetectionOutput(interpreter, threshold=0.5); + console.log('Detected objects:', objects); + for (obj of objects) { + console.log(obj); + const x = obj.bbox.xmin * width; + const y = obj.bbox.ymin * height; + const w = obj.bbox.xmax * width - x; + const h = obj.bbox.ymax * height - y; + ctx.strokeRect(x, y, w, h); + ctx.fillText(model.labels[obj.id], x + 5, y + 5); + } + label = `${objects.length} ${objects.length == 1 ? 'object' : 'objects'}`; + break; + } + document.getElementById("result").textContent = `${label}: ${inferenceTime} ms`; }); }; Module['print'] = txt => console.log(txt);
diff --git a/site/imagenet_labels.js b/site/labels.js similarity index 95% rename from site/imagenet_labels.js rename to site/labels.js index fb03f1c..b47648c 100644 --- a/site/imagenet_labels.js +++ b/site/labels.js
@@ -14,7 +14,7 @@ * limitations under the License. * ============================================================================= */ -let imagenet_labels = [ +const imagenet_labels = [ "background", "tench, Tinca tinca", "goldfish, Carassius auratus", @@ -1017,3 +1017,96 @@ "ear, spike, capitulum", "toilet tissue, toilet paper, bathroom tissue" ]; + +const coco_labels = [ + 'person', + 'bicycle', + 'car', + 'motorcycle', + 'airplane', + 'bus', + 'train', + 'truck', + 'boat', + 'traffic light', + 'fire hydrant', + 'n/a', + 'stop sign', + 'parking meter', + 'bench', + 'bird', + 'cat', + 'dog', + 'horse', + 'sheep', + 'cow', + 'elephant', + 'bear', + 'zebra', + 'giraffe', + 'n/a', + 'backpack', + 'umbrella', + 'n/a', + 'n/a', + 'handbag', + 'tie', + 'suitcase', + 'frisbee', + 'skis', + 'snowboard', + 'sports ball', + 'kite', + 'baseball bat', + 'baseball glove', + 'skateboard', + 'surfboard', + 'tennis racket', + 'bottle', + 'n/a', + 'wine glass', + 'cup', + 'fork', + 'knife', + 'spoon', + 'bowl', + 'banana', + 'apple', + 'sandwich', + 'orange', + 'broccoli', + 'carrot', + 'hot dog', + 'pizza', + 'donut', + 'cake', + 'chair', + 'couch', + 'potted plant', + 'bed', + 'n/a', + 'dining table', + 'n/a', + 'n/a', + 'toilet', + 'n/a', + 'tv', + 'laptop', + 'mouse', + 'remote', + 'keyboard', + 'cell phone', + 'microwave', + 'oven', + 'toaster', + 'sink', + 'refrigerator', + 'n/a', + 'book', + 'clock', + 'vase', + 'scissors', + 'teddy bear', + 'hair drier', + 'toothbrush', +];
diff --git a/site/tflite.js b/site/tflite.js index 97d373f..1547317 100644 --- a/site/tflite.js +++ b/site/tflite.js
@@ -14,7 +14,7 @@ * limitations under the License. * ============================================================================= */ -let tflite = {}; +const tflite = {}; (function() { 'use strict'; @@ -22,8 +22,8 @@ let nextId = 0; function rgbaArrayToRgbArray(rgbaArray) { - var rgbArray = new Uint8Array(new ArrayBuffer(3 * rgbaArray.length / 4)); - for (var i = 0, j = 0; i < rgbaArray.length; i += 4, j += 3) { + const rgbArray = new Uint8Array(new ArrayBuffer(3 * rgbaArray.length / 4)); + for (let i = 0, j = 0; i < rgbaArray.length; i += 4, j += 3) { rgbArray[j + 0] = rgbaArray[i + 0]; rgbArray[j + 1] = rgbaArray[i + 1]; rgbArray[j + 2] = rgbaArray[i + 2]; @@ -35,6 +35,55 @@ return 'interpreter_' + id; } + tflite.setRgbInput = function(interpreter, rgbArray, index=0) { + const shape = interpreter.inputShape(index); + if (rgbArray.length != shape.reduce((a, b) => a * b)) + throw new Error('Invalid input array size'); + + writeArrayToMemory(rgbArray, interpreter.inputBuffer(index)); + } + + tflite.setRgbaInput = function(interpreter, rgbaArray) { + tflite.setRgbInput(interpreter, rgbaArrayToRgbArray(rgbaArray)); + } + + tflite.getClassificationOutput = function(interpreter, index=0) { + const count = interpreter.outputShape(index).reduce((a, b) => a * b); + const scoresPtr = interpreter.outputBuffer(index) / Module.HEAPU8.BYTES_PER_ELEMENT; + const scores = Module.HEAPU8.slice(scoresPtr, scoresPtr + count); + return scores.indexOf(Math.max(...scores)); + } + + tflite.getDetectionOutput = function(interpreter, threshold=0.0) { + const bboxesPtr = interpreter.outputBuffer(0) / Module.HEAPF32.BYTES_PER_ELEMENT; + const idsPtr = interpreter.outputBuffer(1) / Module.HEAPF32.BYTES_PER_ELEMENT; + const scoresPtr = interpreter.outputBuffer(2) / Module.HEAPF32.BYTES_PER_ELEMENT; + const countPtr = interpreter.outputBuffer(3) / Module.HEAPF32.BYTES_PER_ELEMENT; + + const count = Math.round(Module.HEAPF32[countPtr]); + const bboxes = Module.HEAPF32.slice(bboxesPtr, bboxesPtr + 4 * count); + const ids = Module.HEAPF32.slice(idsPtr, idsPtr + count); + const scores = Module.HEAPF32.slice(scoresPtr, scoresPtr + count); + + const objects = []; + for (let i = 0; i < count; ++i) { + if (scores[i] < threshold) + break; + + objects.push({ + 'id': ids[i], + 'score': scores[i], + 'bbox' : { + 'ymin': Math.max(0.0, bboxes[4 * i]), + 'xmin': Math.max(0.0, bboxes[4 * i + 1]), + 'ymax': Math.min(1.0, bboxes[4 * i + 2]), + 'xmax': Math.min(1.0, bboxes[4 * i + 3]), + }, + }); + } + return objects; + } + tflite.Interpreter = function() { this.interpreter_create = Module.cwrap('interpreter_create', 'number', ['number'], { async: true }); this.interpreter_destroy = Module.cwrap('interpreter_destroy', null, ['number']); @@ -54,16 +103,52 @@ this.id = nextId++; Module['invokeDone'] = function(id) { - let key = callbackKey(id); - let callback = Module[key]; + const key = callbackKey(id); + const callback = Module[key]; if (callback) callback(); delete Module[key]; }; } - tflite.Interpreter.prototype.create = async function(modelBuffer, modelBufferSize) { - this.interpreter = await this.interpreter_create(modelBuffer, modelBufferSize, 0); - return this.interpreter != null; + tflite.Interpreter.prototype.createFromBuffer = async function(buffer) { + const model = new Uint8Array(buffer); + const modelBufferSize = model.length * model.BYTES_PER_ELEMENT; + const modelBufferPtr = Module._malloc(modelBufferSize); + Module.HEAPU8.set(model, modelBufferPtr); + this.interpreter = await this.interpreter_create(modelBufferPtr, modelBufferSize, 0); + + if (this.interpreter == null) + return false; + + this.input_shapes = []; + this.input_buffers = []; + const num_inputs = this.interpreter_num_inputs(this.interpreter); + for (let ti = 0; ti < num_inputs; ++ti) { + const shape = []; + const dims = this.interpreter_num_input_dims(this.interpreter, ti); + for (let i = 0; i < dims; ++i) + shape.push(this.interpreter_input_dim(this.interpreter, ti, i)); + this.input_shapes.push(shape); + + const buffer = this.interpreter_input_buffer(this.interpreter, ti); + this.input_buffers.push(buffer); + } + + this.output_shapes = []; + this.output_buffers = []; + const num_outputs = this.interpreter_num_outputs(this.interpreter); + for (let ti = 0; ti < num_outputs; ++ti) { + const shape = []; + const dims = this.interpreter_num_output_dims(this.interpreter, ti); + for (let i = 0; i < dims; ++i) + shape.push(this.interpreter_output_dim(this.interpreter, ti, i)); + this.output_shapes.push(shape); + + const buffer = this.interpreter_output_buffer(this.interpreter, ti); + this.output_buffers.push(buffer); + } + + return true; } tflite.Interpreter.prototype.destroy = function() { @@ -71,58 +156,34 @@ } tflite.Interpreter.prototype.numInputs = function() { - return this.interpreter_num_inputs(this.interpreter); + return this.input_shapes.length; } tflite.Interpreter.prototype.inputBuffer = function(index) { - return this.interpreter_input_buffer(this.interpreter, index); + return this.input_buffers[index]; } tflite.Interpreter.prototype.inputShape = function(index) { - let dims = this.interpreter_num_input_dims(this.interpreter, index); - let shape = []; - for (let i = 0; i < dims; ++i) - shape.push(this.interpreter_input_dim(this.interpreter, index, i)); - return shape; + return this.input_shapes[index]; } tflite.Interpreter.prototype.numOutputs = function() { - return this.interpreter_num_outputs(this.interpreter); + return this.output_shapes.length; } tflite.Interpreter.prototype.outputBuffer = function(index) { - return this.interpreter_output_buffer(this.interpreter, index); + return this.output_buffers[index]; } tflite.Interpreter.prototype.outputShape = function(index) { - let dims = this.interpreter_num_output_dims(this.interpreter, index); - let shape = []; - for (let i = 0; i < dims; ++i) - shape.push(this.interpreter_output_dim(this.interpreter, index, i)); - return shape; + return this.output_shapes[index]; } - tflite.Interpreter.prototype.invoke = function(callback) { - Module[callbackKey(this.id)] = callback; - this.interpreter_invoke_async(this.interpreter, this.id); - } - - tflite.Interpreter.prototype.setRgbInput = function(index, rgbArray) { - let shape = this.inputShape(index); - if (rgbArray.length != shape.reduce((a, b) => a * b)) - throw new Error('Invalid input array size'); - - writeArrayToMemory(rgbArray, this.inputBuffer(index)); - } - - tflite.Interpreter.prototype.setRgbaInput = function(index, rgbaArray) { - this.setRgbInput(index, rgbaArrayToRgbArray(rgbaArray)); - } - - tflite.Interpreter.prototype.getClassificationOutput = function(index, rgbaArray) { - let size = this.outputShape(index).reduce((a, b) => a * b); - let buf = this.outputBuffer(index); - let tensor = Module.HEAPU8.slice(buf, buf + size); - return tensor.indexOf(Math.max(...tensor)) + tflite.Interpreter.prototype.invoke = function() { + const self = this; + return new Promise(resolve => { + Module[callbackKey(self.id)] = resolve; + self.interpreter_invoke_async(self.interpreter, self.id); + }); } })();
diff --git a/tflite/libusb.cc b/tflite/libusb.cc index 6195c93..18ac6f6 100644 --- a/tflite/libusb.cc +++ b/tflite/libusb.cc
@@ -25,6 +25,18 @@ #define LIBUSB_NANO 0 #define LIBUSB_RC "" +//#define LIBUSB_ENABLE_LOG + +#ifdef LIBUSB_ENABLE_LOG +#define LIBUSB_LOG(...) \ + do { \ + fprintf(stdout, __VA_ARGS__); \ + fflush(stdout); \ + } while (false) +#else // LIBUSB_ENABLE_LOG +#define LIBUSB_LOG(...) +#endif // LIBUSB_ENABLE_LOG + struct libusb_device { uint8_t bus_number; uint8_t port_number; @@ -54,7 +66,8 @@ static int js_request_device(struct libusb_device *dev) { return MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { - console.log('js_request_device'); + //console.log('js_request_device'); + // Bus 001 Device 005: ID 1a6e:089a Global Unichip Corp. // Bus 002 Device 007: ID 18d1:9302 Google Inc. let options = {'filters': [{'vendorId': 0x18d1, 'productId': 0x9302}]}; @@ -69,7 +82,7 @@ } } - console.log('js_request_device, device list:', devices); + //console.log('js_request_device, device list:', devices); if (devices.length === 1) { let d = devices[0]; @@ -94,7 +107,7 @@ uint16_t wIndex, uint8_t *data, uint16_t wLength, unsigned int timeout) { return MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { - console.log('js_control_transfer'); + //console.log('js_control_transfer'); let bmRequestType = $0; let bRequest = $1; @@ -160,7 +173,7 @@ extern "C" { int libusb_init(libusb_context **ctx) { - std::cout << "libusb_init" << std::endl; + LIBUSB_LOG("libusb_init"); if (!EM_ASM_INT(return navigator.usb !== undefined)) return LIBUSB_ERROR_NOT_SUPPORTED; @@ -170,21 +183,21 @@ } void LIBUSB_CALL libusb_exit(libusb_context *ctx) { - std::cout << "libusb_exit" << std::endl; + LIBUSB_LOG("libusb_exit"); delete ctx; } void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level) { - std::cout << "<NOT IMPLEMENTED> libusb_set_debug" << std::endl; + LIBUSB_LOG("<NOT IMPLEMENTED> libusb_set_debug"); } const struct libusb_version* LIBUSB_CALL libusb_get_version() { - std::cout << "libusb_get_version" << std::endl; + LIBUSB_LOG("libusb_get_version"); return &libusb_version_internal; } struct libusb_transfer* LIBUSB_CALL libusb_alloc_transfer(int iso_packets) { - std::cout << "libusb_alloc_transfer" << std::endl; + LIBUSB_LOG("libusb_alloc_transfer"); size_t size = sizeof(struct libusb_transfer) + sizeof(struct libusb_iso_packet_descriptor) * iso_packets; @@ -193,7 +206,7 @@ } int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer) { - std::cout << "libusb_submit_transfer" << std::endl; + LIBUSB_LOG("libusb_submit_transfer"); bool dir_in = (transfer->endpoint & 0x80) == 0x80; uint8_t endpoint = transfer->endpoint & 0x7f; @@ -203,7 +216,8 @@ case LIBUSB_TRANSFER_TYPE_INTERRUPT: if (dir_in) { MAIN_THREAD_ASYNC_EM_ASM({ - console.log('js_submit_bulk_in_transfer, endpoint: ', $0); + //console.log('js_submit_bulk_in_transfer, endpoint: ', $0); + this.libusb_device.transferIn($0, $2).then(function(result) { var data = new Uint8Array(result.data.buffer); writeArrayToMemory(data, $1); @@ -215,7 +229,7 @@ }, endpoint, transfer->buffer, transfer->length, transfer); } else { MAIN_THREAD_ASYNC_EM_ASM({ - console.log('js_submit_bulk_out_transfer, endpoint: ', $0); + //console.log('js_submit_bulk_out_transfer, endpoint: ', $0); var data = new Uint8Array($2); for(let i = 0; i < $2; ++i) @@ -231,29 +245,29 @@ } break; default: - printf("Transfer type not implemented: %u\n", transfer->type); + LIBUSB_LOG("Transfer type not implemented: %u\n", transfer->type); return LIBUSB_ERROR_IO; } return LIBUSB_SUCCESS; } int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer) { - std::cout << "<NOT IMPLEMENTED> libusb_cancel_transfer" << std::endl; + LIBUSB_LOG("<NOT IMPLEMENTED> libusb_cancel_transfer"); return 0; } void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer) { - std::cout << "libusb_free_transfer" << std::endl; + LIBUSB_LOG("libusb_free_transfer"); free(transfer); } uint8_t libusb_get_port_number(libusb_device * dev) { - std::cout << "libusb_get_port_number" << std::endl; + LIBUSB_LOG("libusb_get_port_number"); return dev->port_number; } int libusb_get_port_numbers(libusb_device *dev,uint8_t *port_numbers, int port_numbers_len) { - std::cout << "libusb_get_port_numbers" << std::endl; + LIBUSB_LOG("libusb_get_port_numbers"); if (port_numbers_len <= 0) return LIBUSB_ERROR_INVALID_PARAM; @@ -270,7 +284,7 @@ while (true) { if (auto item = ctx->completed_transfers.Pop(25)) { auto* transfer = item.value(); - std::cout << "== Running callback ==" << std::endl; + //std::cout << "== Running callback ==" << std::endl; transfer->callback(transfer); } else { break; @@ -280,11 +294,12 @@ } int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev) { - std::cout << "libusb_reset_device" << std::endl; + LIBUSB_LOG("libusb_reset_device"); + return MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { try { - console.log('js_reset_device'); + //console.log('js_reset_device'); await this.libusb_device.reset(); return 0; // LIBUSB_SUCCESS } catch (error) { @@ -299,31 +314,31 @@ int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout) { - std::cout << "libusb_control_transfer" << std::endl; + LIBUSB_LOG("libusb_control_transfer"); return js_control_transfer(request_type, bRequest, wValue, wIndex, data, wLength, timeout); } int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout) { - std::cout << "<NOT IMPLEMENTED> libusb_bulk_transfer" << std::endl; + LIBUSB_LOG("<NOT IMPLEMENTED> libusb_bulk_transfer"); return 0; } int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *actual_length, unsigned int timeout) { - std::cout << "<NOT IMPLEMENTED> libusb_interrupt_transfer" << std::endl; + LIBUSB_LOG("<NOT IMPLEMENTED> libusb_interrupt_transfer"); return 0; } int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle) { - std::cout << "libusb_open" << std::endl; + LIBUSB_LOG("libusb_open"); // dev->descriptor.idVendor, dev->descriptor.idProduct MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { - console.log('js_open_device'); + //console.log('js_open_device'); await this.libusb_device.open(); try { await this.libusb_device.reset(); // TODO(dkovalev) @@ -343,11 +358,11 @@ } void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle) { - std::cout << "libusb_close" << std::endl; + LIBUSB_LOG("libusb_close"); MAIN_THREAD_EM_ASM_INT({ Asyncify.handleAsync(async () => { - console.log('js_close_device'); + //console.log('js_close_device'); return await this.libusb_device.close(); }); }); @@ -356,12 +371,12 @@ } libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) { - std::cout << "libusb_get_device" << std::endl; + LIBUSB_LOG("libusb_get_device"); return dev_handle->dev; } ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list) { - std::cout << "libusb_get_device_list" << std::endl; + LIBUSB_LOG("libusb_get_device_list"); auto* dev = &ctx->dev; dev->ctx = ctx; @@ -377,7 +392,7 @@ } void LIBUSB_CALL libusb_free_device_list(libusb_device* *list, int unref_devices) { - std::cout << "libusb_free_device_list: unref_devices=" << unref_devices << std::endl; + LIBUSB_LOG("libusb_free_device_list: unref_devices=%d", unref_devices); int i = 0; while (true) { @@ -390,32 +405,32 @@ } int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc) { - std::cout << "libusb_get_device_descriptor" << std::endl; + LIBUSB_LOG("libusb_get_device_descriptor"); *desc = dev->descriptor; return 0; } int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev) { - std::cout << "libusb_get_device_speed" << std::endl; + LIBUSB_LOG("libusb_get_device_speed"); return LIBUSB_SPEED_SUPER; // TODO(dkovalev) } uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev) { - std::cout << "libusb_get_bus_number" << std::endl; + LIBUSB_LOG("libusb_get_bus_number"); return dev->bus_number; } int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, int configuration) { - std::cout << "<NOT IMPLEMENTED> libusb_set_configuration" << std::endl; + LIBUSB_LOG("<NOT IMPLEMENTED> libusb_set_configuration"); return 0; } int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, int interface_number) { - std::cout << "libusb_claim_interface: " << interface_number << std::endl; + LIBUSB_LOG("libusb_claim_interface: %d", interface_number); return MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { try { - console.log('js_claim_interface: ', $0); + //console.log('js_claim_interface: ', $0); await this.libusb_device.claimInterface($0); return 0; // LIBUSB_SUCCESS } catch (error) { @@ -427,11 +442,11 @@ } int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, int interface_number) { - std::cout << "libusb_release_interface: " << interface_number << std::endl; + LIBUSB_LOG("libusb_release_interface: %d", interface_number); return MAIN_THREAD_EM_ASM_INT({ return Asyncify.handleAsync(async () => { try { - console.log('js_release_interface: ', $0, this.libusb_device); + //console.log('js_release_interface: ', $0, this.libusb_device); await this.libusb_device.releaseInterface($0); return 0; // LIBUSB_SUCCESS } catch (error) { @@ -444,7 +459,7 @@ EMSCRIPTEN_KEEPALIVE void set_transfer_error(struct libusb_transfer* transfer) { - std::cout << "==> set_tansfer_error [" << transfer << "]" << std::endl; + LIBUSB_LOG("==> set_tansfer_error [%p]", transfer); libusb_context* ctx = transfer->dev_handle->dev->ctx; transfer->status = LIBUSB_TRANSFER_CANCELLED; @@ -454,7 +469,7 @@ } EMSCRIPTEN_KEEPALIVE void set_transfer_completed(struct libusb_transfer* transfer, int actual_length) { - std::cout << "==> set_tansfer_completed [" << transfer << "]: " << actual_length << std::endl; + LIBUSB_LOG("==> set_tansfer_completed [%p]: %d", transfer, actual_length); libusb_context* ctx = transfer->dev_handle->dev->ctx; transfer->status = LIBUSB_TRANSFER_COMPLETED;