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;