diff --git a/packages/usb/blink-led-pwm.js b/packages/usb/blink-led-pwm.js index 6bbd81ac..c77a98d1 100755 --- a/packages/usb/blink-led-pwm.js +++ b/packages/usb/blink-led-pwm.js @@ -1,16 +1,12 @@ #!/usr/bin/env node -let uhk = require('./uhk'); +const uhk = require('./uhk'); -let delayCycle = true; let areLedsEnabled = true; -uhk.sendUsbPacketsByCallback(() => { - delayCycle = !delayCycle; - if (delayCycle) { - return new uhk.DelayMs(500); - } else { - areLedsEnabled = !areLedsEnabled; - let brightnessPercent = areLedsEnabled ? 100 : 0; - return new Buffer([uhk.usbCommands.setLedPwm, brightnessPercent]); - } -}); +const device = uhk.getUhkDevice(); +setInterval(() => { + areLedsEnabled = !areLedsEnabled; + const brightnessPercent = areLedsEnabled ? 100 : 0; + + device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.setLedPwm, brightnessPercent]))); +}, 500); diff --git a/packages/usb/blink-test-leds.js b/packages/usb/blink-test-leds.js index 59268204..771f3919 100755 --- a/packages/usb/blink-test-leds.js +++ b/packages/usb/blink-test-leds.js @@ -1,15 +1,11 @@ #!/usr/bin/env node let uhk = require('./uhk'); -let delayCycle = true; let areLedsEnabled = true; -uhk.sendUsbPacketsByCallback(() => { - delayCycle = !delayCycle; - if (delayCycle) { - return new uhk.DelayMs(500); - } else { - areLedsEnabled = !areLedsEnabled; - return new Buffer([uhk.usbCommands.setTestLed, areLedsEnabled ? 1 : 0]); - } -}); +const device = uhk.getUhkDevice(); +setInterval(() => { + areLedsEnabled = !areLedsEnabled; + + device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.setTestLed, areLedsEnabled ? 1 : 0]))); +}, 500); diff --git a/packages/usb/eeprom.js b/packages/usb/eeprom.js index de6f684b..ba760d73 100755 --- a/packages/usb/eeprom.js +++ b/packages/usb/eeprom.js @@ -1,32 +1,17 @@ #!/usr/bin/env node -let fs = require('fs'); -let uhk = require('./uhk'); +const uhk = require('./uhk'); -let eepromTransferType = process.argv[2]; -let eepromTransferId = uhk.eepromTransfer[eepromTransferType]; +const eepromTransferType = process.argv[2]; +const eepromTransferId = uhk.eepromTransfer[eepromTransferType]; if (eepromTransferId === undefined) { console.error(`Gotta provide one of ${Object.keys(uhk.eepromTransfer).join(', ')}`); process.exit(1); } -let isFirstSend = true; -let isFirstReceive = true; -let isEepromBusy = true; - -uhk.sendUsbPacketsByCallback(() => { - if (isFirstSend) { - isFirstSend = false; - return new Buffer([uhk.usbCommands.launchEepromTransfer, eepromTransferId]); - } else { - return isEepromBusy ? new Buffer([uhk.usbCommands.getKeyboardState]) : null; - } -}); - -uhk.registerReceiveCallback((buffer) => { - if (isFirstReceive) { - isFirstReceive = false; - } else { - isEepromBusy = buffer[1] === 1; - } -}); +const device = uhk.getUhkDevice(); +device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.launchEepromTransfer, eepromTransferId]))); +const buffer = Buffer.from(device.readSync()); +if(buffer[1] === 1) { + device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.getKeyboardState]))); +} diff --git a/packages/usb/get-config-size.js b/packages/usb/get-config-size.js index 0d058331..d3d215b9 100755 --- a/packages/usb/get-config-size.js +++ b/packages/usb/get-config-size.js @@ -1,17 +1,14 @@ #!/usr/bin/env node -let uhk = require('./uhk'); -let process = require('process'); +const uhk = require('./uhk'); -uhk.silent = true; -let isHardwareConfig = process.argv[2] === 'h'; -let configTypeString = isHardwareConfig ? 'hardware' : 'user'; +const isHardwareConfig = process.argv[2] === 'h'; -uhk.sendUsbPacketsByCallback(() => { - return new Buffer([uhk.usbCommands.getProperty, isHardwareConfig ? uhk.systemPropertyIds.hardwareConfigSize : uhk.systemPropertyIds.userConfigSize]); -}); +const device = uhk.getUhkDevice(); +const sendData = new Buffer([uhk.usbCommands.getProperty, + isHardwareConfig ? + uhk.systemPropertyIds.hardwareConfigSize + : uhk.systemPropertyIds.userConfigSize]); -uhk.registerReceiveCallback((buffer) => { - configSize = buffer[1] + (buffer[2]<<8); - console.log(configSize); - process.exit(0); -}); +device.write(uhk.getTransferData(sendData)); +const response = Buffer.from(device.readSync()); +console.log(response[1] + (response[2]<<8)); diff --git a/packages/usb/jump-to-bootloader.js b/packages/usb/jump-to-bootloader.js index eb2b232f..7ffe2d8d 100755 --- a/packages/usb/jump-to-bootloader.js +++ b/packages/usb/jump-to-bootloader.js @@ -9,7 +9,9 @@ console.log('Trying to jump to the bootloader...'); setInterval(() => { timeoutMs -= pollingIntervalMs; - if (uhk.getBootloaderDevice()) { + let device = uhk.getBootloaderDevice(); + + if (device) { console.log('Bootloader is up'); process.exit(0); } @@ -19,9 +21,10 @@ setInterval(() => { process.exit(1); } - if (uhk.getUhkDevice() && !jumped) { + device = uhk.getUhkDevice(); + if (device && !jumped) { console.log('UHK found, jumping to bootloader'); - uhk.sendUsbPacket(new Buffer([uhk.usbCommands.jumpToBootloader]), {noReceive:true}); + device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.jumpToBootloader]))); jumped = true; } diff --git a/packages/usb/legacy/UhkConnection.js b/packages/usb/legacy/UhkConnection.js deleted file mode 100644 index 9e4d8c73..00000000 --- a/packages/usb/legacy/UhkConnection.js +++ /dev/null @@ -1,212 +0,0 @@ -var usb = require('usb'); -var R = require('ramda'); -var s = require('underscore.string'); - -var UhkConnection = function(selectedLogLevel) { - 'use strict'; - var self = this; - - // Public methods - - self.sendRequest = function(command, arg, callback, shouldReceiveResponse) { - if (shouldReceiveResponse === undefined) { - shouldReceiveResponse = true; - } - - var request; - if (arg === null) { - request = new Buffer([command]); - } else if (typeof arg === 'number') { - request = new Buffer([command, arg]); - } else if (typeof arg === 'string') { - var charCodes = arg.split('').map(function(char) {return char.charCodeAt(0)}); - request = new Buffer([command].concat(charCodes)); - } else { - throw new Error('UhkConnection.sendRequest(): arg is of unknown type'); - } - - log(UhkConnection.LOG_LEVELS.TRANSFER, 'Sending request', request); - setReport(request, function() { - if (shouldReceiveResponse) { - receiveResponse(UhkConnection.LOG_LEVELS.IGNORED_TRANSFER, function() { - // The first response is cached by the OS so let's ignore it and go for the second one. - receiveResponse(UhkConnection.LOG_LEVELS.TRANSFER, callback); - }); - } else { - callback(); - } - }); - }; - - // Private methods - - function setReport(message, callback) { - device.controlTransfer( - 0x21, // bmRequestType (constant for this control request) - 0x09, // bmRequest (constant for this control request) - 0, // wValue (MSB is report type, LSB is report number) - 0, // wIndex (interface number) - message, // message to be sent - callback - ); - } - - function receiveResponse(logLevel, callback) { - var endpoint = usbInterface.endpoints[0]; - var readLength = 64; - endpoint.transfer(readLength, function(error, data) { - if (error) { - log(logLevel, 'Error response received', error); - } else { - log(logLevel, 'Received response:', data); - } - callback(error, data) - }); - } - - function setConfiguration(callback) { - device.controlTransfer( // Send a Set Configuration control request - 0, // bmRequestType - 0x09, // bmRequest - 0, // wValue (Configuration value) - UhkConnection.GENERIC_HID_INTERFACE_ID, // wIndex - new Buffer(0), // message to be sent - callback // callback to be executed upon finishing the transfer - ); - } - - function log(logLevel, message) { - var args = Array.prototype.slice.call(arguments); - args.shift(); - if (logLevel & selectedLogLevel) { - console.log.apply(this, args); - } - } - - // Initialize - - var device; - var usbInterface; - - self.connect = function(errorCallback) { - pollUntil(function() { - var foundDevices = findDevices(); - if (foundDevices.length > 0) { - var foundDevice = foundDevices[0]; - console.log('UHK connected in %s mode.', - foundDevice.enumerationMode.id); - - device = foundDevice.device; - try { - device.open(); // TODO: What if multiple keyboards are plugged in? - } catch (error) { - if (error.errno === -3) { - console.log('Unable to open USB device of VID %s and PID %s. Please fix permissions!', - s.pad(UhkConnection.VENDOR_ID.toString(16), 4, '0'), - s.pad(foundDevice.enumerationMode.productId.toString(16), 4, '0')); - process.exit(1); - } else { - throw error; - } - } - - usbInterface = self.usbInterface = device.interface(0); - if (usbInterface.isKernelDriverActive()) { - usbInterface.detachKernelDriver(); - } - - process.on('exit', attachKernelDriver); - process.on('SIGINT', attachKernelDriver); - process.on('uncaughtException', attachKernelDriver); - - usbInterface.claim(); - setConfiguration(errorCallback); - return true; - } - - return false; - }, - function() { - errorCallback('Could not connect to the UHK. Is it connected to the host?'); - }); - }; - - self.waitUntilDisconnect = function(errorCallback, successCallback) { - pollUntil(function() { - if (findDevices().length === 0) { - successCallback(); - usbInterface = undefined; - return true; - } - - return false; - }, - function() { - errorCallback('Could not disconnect the UHK'); - }); - }; - - function findDevices() { - return UhkConnection.ENUMERATION_MODES.map(function(enumerationMode) { - return { - enumerationMode: enumerationMode, - device: usb.findByIds(UhkConnection.VENDOR_ID, enumerationMode.productId) - } - }).filter(R.prop('device')); - } - - function pollUntil(pollCallback, errorCallback) { - var retryTimeout = 5000; // ms - var retryInterval = 200; // ms - - function keepPolling() { - if (pollCallback()) { - return; - } - - if (retryTimeout <= 0) { - return errorCallback(); - } - - retryTimeout -= retryInterval; - setTimeout(keepPolling, retryInterval); - } - - keepPolling(); - } - - function attachKernelDriver() { - if (usbInterface) { - usbInterface.release(); - if (!usbInterface.isKernelDriverActive()) { - usbInterface.attachKernelDriver(); - } - usbInterface = undefined; - } - } -}; - -UhkConnection.VENDOR_ID = 0x16d2; // TODO: Restore to 0x16d0 for the final prototype. -UhkConnection.GENERIC_HID_INTERFACE_ID = 2; - -UhkConnection.LOG_LEVELS = { - TRANSFER: 0x01, - IGNORED_TRANSFER: 0x02, - ALL: 0xff -}; - -UhkConnection.COMMANDS = { - DETECT: -1, - REENUMERATE: 0, - READ_EEPROM: 67, - WRITE_EEPROM: 1 -}; - -UhkConnection.ENUMERATION_MODES = [ - {id:'KEYBOARD_6KRO', enumerationId:0, productId:0x05ea}, - {id:'KEYBOARD_NKRO', enumerationId:3, productId:0x05eb}, // TODO: Implement this mode in firmware. - {id:'BOOTLOADER_RIGHT', enumerationId:1, productId:0x05ec}, // CDC bootloader - {id:'BOOTLOADER_LEFT', enumerationId:2, productId:0x05ed} // USB to serial -]; - -module.exports = UhkConnection; diff --git a/packages/usb/legacy/uhkcmd b/packages/usb/legacy/uhkcmd deleted file mode 100755 index 36601c28..00000000 --- a/packages/usb/legacy/uhkcmd +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var UhkConnection = require('./UhkConnection'); -var R = require('ramda'); -var path = require('path'); - -var ENUMERATION_MODE_IDS = R.pluck('id', UhkConnection.ENUMERATION_MODES); -var commands = getTypistFriendlyObjectKeys(R.keys(UhkConnection.COMMANDS)); -var args = process.argv.slice(1); -var programName = path.basename(args.shift()); -var commandArg = args.shift(); - -if (!R.contains(commandArg, commands)) { - console.error('Usage: ' + programName + ' COMMAND [ARG]'); - console.error(commandArg === undefined - ? 'No command has been specified.' - : 'Command "' + commandArg + '" is invalid.'); - console.error('Valid commands: ' + commands.join(', ')); - exitWithError(); -} - -var command = UhkConnection.COMMANDS[getTypistUnfriendlyObjectKey(commandArg)]; -var uhkConnection; - -switch (command) { - case UhkConnection.COMMANDS.DETECT: - uhkConnection = new UhkConnection(/*UhkConnection.LOG_LEVELS.TRANSFER*/); - uhkConnection.connect(function(error) { - if (error) { - console.error(error); - exitWithError(); - } - }); - break; - case UhkConnection.COMMANDS.REENUMERATE: - var enumerationModeArg = args.shift(); - var enumerationModes = getTypistFriendlyObjectKeys(ENUMERATION_MODE_IDS); - if (!R.contains(enumerationModeArg, enumerationModes)) { - console.error('Usage: %s %s {%s}', programName, commandArg, enumerationModes.join(' | ')); - console.error(enumerationModeArg === undefined - ? 'No enumeration mode has been specified.' - : 'Enumeration mode "%s" is invalid.', enumerationModeArg); - exitWithError(); - } - var enumerationMode = R.find(R.propEq('id', getTypistUnfriendlyObjectKey(enumerationModeArg)), - UhkConnection.ENUMERATION_MODES); - sendRequest(command, enumerationMode.enumerationId, function(error, data) { - console.log('Reenumerating the UHK in %s mode...', getTypistUnfriendlyObjectKey(enumerationMode.id)); - uhkConnection.waitUntilDisconnect(function() {}, function() { - console.log('UHK disconnected.'); - uhkConnection.connect(function() {}); - }); - }, false); - break; - case UhkConnection.COMMANDS.READ_EEPROM: - sendRequest(command, null, function(error, data) { - console.log(data); - }); - break; - case UhkConnection.COMMANDS.WRITE_EEPROM: - var stringToBeSaved = args.shift(); - if (!stringToBeSaved) { - console.error('A string has to be specified to be saved into the EEPROM.'); - exitWithError(); - } - sendRequest(command, stringToBeSaved, function(error, data) {}); - break; -} - -// Helper functions - -function sendRequest(command, arg, callback, shouldReceiveResponse) { - if (uhkConnection) { - uhkConnection.sendRequest(command, arg, callback, shouldReceiveResponse); - } else { - uhkConnection = new UhkConnection(/*UhkConnection.LOG_LEVELS.TRANSFER*/); - uhkConnection.connect(function(error) { - if (error) { - console.error(error); - exitWithError(); - } - - uhkConnection.sendRequest(command, arg, callback, shouldReceiveResponse); - }); - } -} - -function getTypistFriendlyObjectKeys(object) { - return object.map(function(command) { - return command.toLowerCase().replace(/_/g, '-'); - }); -} - -function getTypistUnfriendlyObjectKey(key) { - return key.toUpperCase().replace(/-/g, '_'); -} - -function exitWithError() { - process.exit(1); -} diff --git a/packages/usb/mess-up-leds.js b/packages/usb/mess-up-leds.js deleted file mode 100755 index 8d05ca48..00000000 --- a/packages/usb/mess-up-leds.js +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env node -let uhk = require('./uhk'); -const LED_CONTROL_REGISTER = 0; -uhk.sendUsbPackets([ - new Buffer([uhk.usbCommands.writeLedDriver, uhk.leftLedDriverAddress, 18, LED_CONTROL_REGISTER, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), - new Buffer([uhk.usbCommands.writeLedDriver, uhk.rightLedDriverAddress, 18, LED_CONTROL_REGISTER, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]) -]); diff --git a/packages/usb/package-lock.json b/packages/usb/package-lock.json index 7aa129e3..21f64ad5 100644 --- a/packages/usb/package-lock.json +++ b/packages/usb/package-lock.json @@ -469,6 +469,771 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" }, + "node-hid": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.5.4.tgz", + "integrity": "sha1-pyRt/AjVJ3QUf6JkNU1dpuq0AlM=", + "requires": { + "nan": "2.6.2", + "node-pre-gyp": "0.6.31" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true + }, + "aproba": { + "version": "1.0.4", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.2", + "bundled": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.2" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true + }, + "aws4": { + "version": "1.5.0", + "bundled": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true + }, + "bcrypt-pbkdf": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.6", + "bundled": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true + }, + "caseless": { + "version": "0.11.0", + "bundled": true + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "bundled": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.9.0", + "bundled": true, + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true + } + } + }, + "debug": { + "version": "2.2.0", + "bundled": true, + "requires": { + "ms": "0.7.1" + } + }, + "deep-extend": { + "version": "0.4.1", + "bundled": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "extend": { + "version": "3.0.0", + "bundled": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true + }, + "form-data": { + "version": "2.1.2", + "bundled": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.14" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "fstream": { + "version": "1.0.10", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.5.4" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "requires": { + "fstream": "1.0.10", + "inherits": "2.0.3", + "minimatch": "3.0.3" + } + }, + "gauge": { + "version": "2.7.2", + "bundled": true, + "requires": { + "aproba": "1.0.4", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.0", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "supports-color": "0.2.0", + "wide-align": "1.1.0" + } + }, + "generate-function": { + "version": "2.0.0", + "bundled": true + }, + "generate-object-property": { + "version": "1.2.0", + "bundled": true, + "requires": { + "is-property": "1.0.2" + } + }, + "getpass": { + "version": "0.1.6", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true + } + } + }, + "glob": { + "version": "7.1.1", + "bundled": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "graceful-readlink": { + "version": "1.0.1", + "bundled": true + }, + "har-validator": { + "version": "2.0.6", + "bundled": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.9.0", + "is-my-json-valid": "2.15.0", + "pinkie-promise": "2.0.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.3.1", + "sshpk": "1.10.2" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.4", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-my-json-valid": { + "version": "2.15.0", + "bundled": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-property": { + "version": "1.0.2", + "bundled": true + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "jsbn": { + "version": "0.1.0", + "bundled": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true + }, + "jsonpointer": { + "version": "4.0.1", + "bundled": true + }, + "jsprim": { + "version": "1.3.1", + "bundled": true, + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + } + }, + "mime-db": { + "version": "1.26.0", + "bundled": true + }, + "mime-types": { + "version": "2.1.14", + "bundled": true, + "requires": { + "mime-db": "1.26.0" + } + }, + "minimatch": { + "version": "3.0.3", + "bundled": true, + "requires": { + "brace-expansion": "1.1.6" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "0.7.1", + "bundled": true + }, + "node-pre-gyp": { + "version": "0.6.31", + "bundled": true, + "requires": { + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.0.2", + "rc": "1.1.6", + "request": "2.79.0", + "rimraf": "2.5.4", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.3.0" + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "npmlog": { + "version": "4.0.2", + "bundled": true, + "requires": { + "are-we-there-yet": "1.1.2", + "console-control-strings": "1.1.0", + "gauge": "2.7.2", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true + }, + "object-assign": { + "version": "4.1.0", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true + }, + "qs": { + "version": "6.3.0", + "bundled": true + }, + "rc": { + "version": "1.1.6", + "bundled": true, + "requires": { + "deep-extend": "0.4.1", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "1.0.4" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true + } + } + }, + "readable-stream": { + "version": "2.2.2", + "bundled": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.79.0", + "bundled": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.5.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.0", + "forever-agent": "0.6.1", + "form-data": "2.1.2", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.14", + "oauth-sign": "0.8.2", + "qs": "6.3.0", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.5.4", + "bundled": true, + "requires": { + "glob": "7.1.1" + } + }, + "semver": { + "version": "5.3.0", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.10.2", + "bundled": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.0", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.6", + "jodid25519": "1.0.2", + "jsbn": "0.1.0", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true + } + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "1.0.4", + "bundled": true + }, + "supports-color": { + "version": "0.2.0", + "bundled": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.10", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.3.0", + "bundled": true, + "requires": { + "debug": "2.2.0", + "fstream": "1.0.10", + "fstream-ignore": "1.0.5", + "once": "1.3.3", + "readable-stream": "2.1.5", + "rimraf": "2.5.4", + "tar": "2.2.1", + "uid-number": "0.0.6" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "bundled": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "readable-stream": { + "version": "2.1.5", + "bundled": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "bundled": true + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.0", + "bundled": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + }, "node-pre-gyp": { "version": "0.6.36", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", diff --git a/packages/usb/package.json b/packages/usb/package.json index 469764fc..0670f06b 100644 --- a/packages/usb/package.json +++ b/packages/usb/package.json @@ -5,8 +5,6 @@ "main": "UhkConnection.js", "license": "GPL-3.0", "dependencies": { - "ramda": "^0.22.1", - "underscore.string": "^3.3.4", - "usb": "git+https://github.com/tessel/node-usb.git#1.3.0" + "node-hid": "0.5.4" } } diff --git a/packages/usb/pulse-leds.js b/packages/usb/pulse-leds.js deleted file mode 100755 index 8f8dbcce..00000000 --- a/packages/usb/pulse-leds.js +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env node -let uhk = require('./uhk'); -let [endpointIn, endpointOut] = uhk.getUsbEndpoints(); - -let ledMatrixSize = 144; -let ledCountToUpdatePerCommand = ledMatrixSize / 3; - -let state = 1; - -let ledsLeft = new Buffer(ledMatrixSize); -let ledsRight = new Buffer(ledMatrixSize); -ledsLeft.fill(0xff) -ledsRight.fill(0xff) - -let ledIndex = 0; -let matrixId = 0; -let ledCommandId = 0; -let letterIdx = 0; - -function updateLeds() { - let buffer = Buffer.concat([ - new Buffer([ - uhk.usbCommands.writeLedDriver, - matrixId ? uhk.rightLedDriverAddress : uhk.leftLedDriverAddress, - ledCountToUpdatePerCommand, - 0x24 + ledIndex - ]), - (matrixId ? ledsRight : ledsLeft).slice(ledIndex, ledIndex + ledCountToUpdatePerCommand) - ]); - console.log('iter: '+letterIdx+' out:', uhk.bufferToString(buffer)) - endpointOut.transfer(buffer, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - - ledIndex += ledCountToUpdatePerCommand; - if (ledIndex >= ledMatrixSize) { - ledIndex = 0; - matrixId = matrixId ? 0 : 1; - } - - updateLeds(); - }) - }); -} - -updateLeds(); - -let lettersLeds = { - 0: [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], - 1: [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], - 2: [1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], - 3: [1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1], - 4: [0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0], - 5: [1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1], - 6: [1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1], - 7: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0], - 8: [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1], - 9: [1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1], - A: [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0], - B: [1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1], - C: [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], - D: [1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1], - E: [1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1], - F: [1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0], - G: [1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1], - H: [0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0], - I: [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], - J: [0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1], - K: [0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0], - L: [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], - M: [0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0], - N: [0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0], - O: [1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1], - P: [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0], - Q: [1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1], - R: [1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0], - S: [1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1], - T: [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], - U: [0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1], - V: [0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0], - W: [0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0], - X: [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0], - Y: [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], - Z: [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1], -} - -let iconLedsToLedMatrix = [0x08, 0x09, 0x0a]; -let layerLedsToLedMatrix = [0x0d, 0x1d, 0x2d]; - -let characterLedsToLedMatrix = [ - [0x0b, 0x1b, 0x29, 0x2a, 0x2b, 0x0c, 0x1c, 0x28, 0x1a, 0x2c, 0x38, 0x39, 0x18, 0x19], - [0x3a, 0x4a, 0x58, 0x59, 0x5a, 0x3b, 0x4b, 0x4c, 0x49, 0x5b, 0x5c, 0x68, 0x3c, 0x48], - [0x69, 0x79, 0x7c, 0x88, 0x89, 0x6a, 0x7a, 0x7b, 0x78, 0x8a, 0x8b, 0x8c, 0x6b, 0x6c] -] - -function setIcons(iconStates) { - for (let i=0; i= digitsAndLetters.length) { - letterIdx = 0; - } - layerLedIdx = ++layerLedIdx % layerLedsToLedMatrix.length; -}, 200); diff --git a/packages/usb/read-adc.js b/packages/usb/read-adc.js index 6815230b..d32b9118 100755 --- a/packages/usb/read-adc.js +++ b/packages/usb/read-adc.js @@ -1,25 +1,16 @@ #!/usr/bin/env node -let uhk = require('./uhk'); -let [endpointIn, endpointOut] = uhk.getUsbEndpoints(); -var arg = process.argv[2] || ''; +const uhk = require('./uhk'); + +const device = uhk.getUhkDevice(); function readAdc() { - var payload = new Buffer([uhk.usbCommands.readAdc]); - console.log('Sending ', uhk.bufferToString(payload)); - endpointOut.transfer(payload, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - console.log('Received', uhk.bufferToString(receivedBuffer), (receivedBuffer[1]*255 + receivedBuffer[0])/4096*5.5*1.045); - setTimeout(readAdc, 500) - }) - }); + const data = uhk.getTransferData(new Buffer([uhk.usbCommands.readAdc])); + console.log('Sending ', data); + device.write(data); + const receivedBuffer = Buffer.from(device.readSync()); + console.log('Received', uhk.bufferToString(receivedBuffer), (receivedBuffer[1]*255 + receivedBuffer[0])/4096*5.5*1.045); + + setTimeout(readAdc, 500) } readAdc(); diff --git a/packages/usb/read-config.js b/packages/usb/read-config.js index 1b26f583..1f6e84ed 100755 --- a/packages/usb/read-config.js +++ b/packages/usb/read-config.js @@ -1,41 +1,37 @@ #!/usr/bin/env node -let fs = require('fs'); -let uhk = require('./uhk'); - +const fs = require('fs'); +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); const chunkSize = 63; let isHardwareConfig = process.argv[2] === 'h'; let configTypeString = isHardwareConfig ? 'hardware' : 'user'; -let isFirstSend = true; -let isFirstReceive = true; let configSize; let offset = 0; let configBuffer = new Buffer(0); let chunkSizeToRead; -uhk.sendUsbPacketsByCallback(() => { - if (isFirstSend) { - isFirstSend = false; - return new Buffer([uhk.usbCommands.getProperty, isHardwareConfig ? uhk.systemPropertyIds.hardwareConfigSize : uhk.systemPropertyIds.userConfigSize]); - } else { - chunkSizeToRead = Math.min(chunkSize, configSize - offset) - let usbCommand = isHardwareConfig ? uhk.usbCommands.readHardwareConfig : uhk.usbCommands.readUserConfig; - let buffer = Buffer([usbCommand, chunkSizeToRead, offset & 0xff, offset >> 8]); - let bufferOrNull = offset >= configSize ? null : buffer; - if (!bufferOrNull) { - fs.writeFileSync(`${configTypeString}-config.read`, configBuffer); - } - offset += chunkSizeToRead; - return bufferOrNull; - } -}); +const payload = new Buffer([ + uhk.usbCommands.getProperty, + isHardwareConfig + ? uhk.systemPropertyIds.hardwareConfigSize + : uhk.systemPropertyIds.userConfigSize + ]); -uhk.registerReceiveCallback((buffer) => { - if (isFirstReceive) { - isFirstReceive = false; - configSize = buffer[1] + (buffer[2]<<8); - console.log(`${configTypeString}configSize:`, configSize); - } else { - configBuffer = Buffer.concat([configBuffer, new Buffer(buffer.slice(1, chunkSizeToRead+1))]); - } -}); +device.write(uhk.getTransferData(payload)); + +let buffer = Buffer.from(device.readSync()); +configSize = buffer[1] + (buffer[2]<<8); +console.log(`${configTypeString}configSize:`, configSize); +while(offset < configSize) { + const usbCommand = isHardwareConfig ? uhk.usbCommands.readHardwareConfig : uhk.usbCommands.readUserConfig; + chunkSizeToRead = Math.min(chunkSize, configSize - offset); + buffer = Buffer.from([usbCommand, chunkSizeToRead, offset & 0xff, offset >> 8]); + device.write(uhk.getTransferData(buffer)); + buffer = Buffer.from(device.readSync()); + console.log('read-config-chunk', uhk.bufferToString(buffer)); + configBuffer = Buffer.concat([configBuffer, new Buffer(buffer.slice(1, chunkSizeToRead + 1))]); + offset += chunkSizeToRead +} +console.log('read ', uhk.bufferToString(configBuffer)); +fs.writeFileSync(`${configTypeString}-config.read`, configBuffer); diff --git a/packages/usb/read-debug-info.js b/packages/usb/read-debug-info.js index 0eeaa60b..912e7e4b 100755 --- a/packages/usb/read-debug-info.js +++ b/packages/usb/read-debug-info.js @@ -1,25 +1,15 @@ #!/usr/bin/env node -let uhk = require('./uhk'); -let [endpointIn, endpointOut] = uhk.getUsbEndpoints(); -var arg = process.argv[2] || ''; +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); function readDebugInfo() { - var payload = new Buffer([uhk.usbCommands.readDebugInfo]); + const payload = new Buffer([uhk.usbCommands.readDebugInfo]); console.log('Sending ', uhk.bufferToString(payload)); - endpointOut.transfer(payload, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - console.log('Received', uhk.bufferToString(receivedBuffer)); - setTimeout(readDebugInfo, 500) - }) - }); + device.write(uhk.getTransferData(payload)); + device.write([64]); + const receivedBuffer = Buffer.from(device.readSync()); + console.log('Received', uhk.bufferToString(receivedBuffer)); + setTimeout(readDebugInfo, 500) } readDebugInfo(); diff --git a/packages/usb/read-eeprom.js b/packages/usb/read-eeprom.js deleted file mode 100755 index 2466ea7d..00000000 --- a/packages/usb/read-eeprom.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node -let uhk = require('./uhk'); -uhk.sendUsbPacket(new Buffer([uhk.usbCommands.readEeprom, 63, 0x00, 0x00])) diff --git a/packages/usb/read-merge-sensor.js b/packages/usb/read-merge-sensor.js index c3671265..b7c4f1e0 100755 --- a/packages/usb/read-merge-sensor.js +++ b/packages/usb/read-merge-sensor.js @@ -1,27 +1,17 @@ #!/usr/bin/env node -let uhk = require('./uhk'); -let [endpointIn, endpointOut] = uhk.getUsbEndpoints(); -var arg = process.argv[2] || ''; +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); function readMergeSensor() { - var payload = new Buffer([uhk.usbCommands.readMergeSensor]); + const payload = new Buffer([uhk.usbCommands.readMergeSensor]); console.log('Sending ', uhk.bufferToString(payload)); - endpointOut.transfer(payload, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - console.log('Received', uhk.bufferToString(receivedBuffer)); - setTimeout(readMergeSensor, 500) - var areHalvesMerged = receivedBuffer[1] === 1; - console.log('The keyboards halves are ' + (areHalvesMerged ? 'merged' : 'split')) - }) - }); + device.write(uhk.getTransferData(payload)); + const receivedBuffer = device.readSync(); + console.log('Received', uhk.bufferToString(receivedBuffer)); + const areHalvesMerged = receivedBuffer[1] === 1; + console.log('The keyboards halves are ' + (areHalvesMerged ? 'merged' : 'split')) + + setTimeout(readMergeSensor, 500) } readMergeSensor(); diff --git a/packages/usb/set-led-pwm.js b/packages/usb/set-led-pwm.js index 518b1135..87a0c28e 100755 --- a/packages/usb/set-led-pwm.js +++ b/packages/usb/set-led-pwm.js @@ -1,5 +1,6 @@ #!/usr/bin/env node -let uhk = require('./uhk'); +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); let programName = process.argv[1]; @@ -9,7 +10,4 @@ if (process.argv.length !== 3) { } let leftBrightnessPercent = process.argv[2] || ''; - -uhk.sendUsbPackets([ - new Buffer([uhk.usbCommands.setLedPwm, +leftBrightnessPercent]), -]); +device.write(uhk.getTransferData(new Buffer([uhk.usbCommands.setLedPwm, +leftBrightnessPercent]))); diff --git a/packages/usb/set-led-values.js b/packages/usb/set-led-values.js deleted file mode 100755 index 9f4c2d0c..00000000 --- a/packages/usb/set-led-values.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env node -let uhk = require('./uhk'); - -let programName = process.argv[1]; - -if (process.argv.length !== 6) { - console.log(`Usage: ${programName} [display 0-255] [left keys 0-255] [unused 0-255] [right keys 0-255]`); - process.exit(1); -} - -let pwmOffset = 0; -let ledDriverAddresses = [uhk.leftLedDriverAddress, uhk.rightLedDriverAddress]; -let ledDriverAddress; -const FRAME_REGISTER_PWM_FIRST = 0x24; - -uhk.sendUsbPacketsByCallback(() => { - if (pwmOffset === 0) { - ledDriverAddress = ledDriverAddresses.shift(); - } - if (!ledDriverAddress) { - return; - } - - let isMatrixA = pwmOffset % 16; - let argIndex = 2 + (ledDriverAddress == uhk.leftLedDriverAddress ? 0 : 2) + (isMatrixA ? 0 : 1); - let val = +process.argv[argIndex]; - let buffer = new Buffer([uhk.usbCommands.writeLedDriver, ledDriverAddress, - 9, FRAME_REGISTER_PWM_FIRST+pwmOffset, val, val, val, val, val, val, val, val]); - pwmOffset += 8; - - if (pwmOffset >= 144) { - pwmOffset = 0; - } - - return buffer; -}); diff --git a/packages/usb/uhk.js b/packages/usb/uhk.js index 1dce6e91..fa7d55bb 100755 --- a/packages/usb/uhk.js +++ b/packages/usb/uhk.js @@ -1,5 +1,4 @@ -let usb = require('usb'); -let receiveCallback; +const HID = require('node-hid'); function bufferToString(buffer) { let str = ''; @@ -9,121 +8,54 @@ function bufferToString(buffer) { hex = '0' + hex; } str += hex; - }; + } return str; } -let usbEndpoints; - function getUhkDevice() { - return usb.findByIds(0x1d50, 0x6122); + const devs = HID.devices() + + const dev = devs.find(x => + x.vendorId === 0x1d50 && + x.productId === 0x6122 && + ((x.usagePage === 128 && x.usage === 129) || x.interface === 0)) + + if (!dev) { + console.error('UHK Device not found:') + return null + } + + return new HID.HID(dev.path) } function getBootloaderDevice() { - return usb.findByIds(0x1d50, 0x6120); -} + const devs = HID.devices() -function getUsbEndpoints() { - let device = getUhkDevice(); - device = getUhkDevice(); - device.open(); + const dev = devs.find(x => + x.vendorId === 0x1d50 + && x.productId === 0x6120) - let usbInterface = device.interface(0); - - // https://github.com/tessel/node-usb/issues/147 - // The function 'isKernelDriverActive' is not available on Windows and not even needed. - if (process.platform !== 'win32' && usbInterface.isKernelDriverActive()) { - usbInterface.detachKernelDriver(); + if (!dev) { + console.error('UHK Bootloader not found:') + return null } - usbInterface.claim(); - - let endpointIn = usbInterface.endpoints[0]; - let endpointOut = usbInterface.endpoints[1]; - return [endpointIn, endpointOut]; -} - -class DelayMs { - constructor(ms) { - this.ms = ms; - } -} - -function registerReceiveCallback(receiveCallbackParam) { - receiveCallback = receiveCallbackParam; -} - -function sendUsbPacketsByCallback(packetProvider, options={}) { - let packet = packetProvider() - - if (packet instanceof DelayMs) { - setTimeout(() => { - sendUsbPacketsByCallback(packetProvider); - }, packet.ms); - return; + else { + console.info(dev) } - if (!(packet instanceof Buffer)) { - return; - } - - if (!moduleExports.silent) { - console.log('Sending: ', bufferToString(packet)); - } - - let [endpointIn, endpointOut] = usbEndpoints || getUsbEndpoints(); - endpointOut.transfer(packet, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - - if (options.noReceive) { - sendUsbPacketsByCallback(packetProvider); - } else { - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - if (!moduleExports.silent) { - console.log('Received:', bufferToString(receivedBuffer)); - } - (receiveCallback || (()=>{}))(receivedBuffer); - sendUsbPacketsByCallback(packetProvider); - }) - } - - }) -} - -function sendUsbPacket(packet, options={}) { - sendUsbPackets([packet], options); -} - -function sendUsbPackets(packets, options={}) { - sendUsbPacketsByCallback(() => { - return packets.shift(); - }, options) + return new HID.HID(dev.path) } exports = module.exports = moduleExports = { - DelayMs, bufferToString, getUhkDevice, getBootloaderDevice, - getUsbEndpoints, - registerReceiveCallback, - sendUsbPacket, - sendUsbPackets, - sendUsbPacketsByCallback, + getTransferData, usbCommands: { getProperty: 0, jumpToBootloader: 1, setTestLed: 2, writeLedDriver: 3, - readLedDriver: 4, - writeEeprom: 5, - readEeprom: 6, readMergeSensor: 7, writeUserConfig: 8, applyConfig: 9, @@ -153,3 +85,24 @@ exports = module.exports = moduleExports = { leftLedDriverAddress: 0b1110100, rightLedDriverAddress: 0b1110111 } + +function convertBufferToIntArray(buffer) { + return Array.prototype.slice.call(buffer, 0) +} + +function getTransferData(buffer) { + const data = convertBufferToIntArray(buffer) + // if data start with 0 need to add additional leading zero because HID API remove it. + // https://github.com/node-hid/node-hid/issues/187 + if (data.length > 0 && data[0] === 0) { +// data.unshift(0) + } + + // From HID API documentation: + // http://www.signal11.us/oss/hidapi/hidapi/doxygen/html/group__API.html#gad14ea48e440cf5066df87cc6488493af + // The first byte of data[] must contain the Report ID. + // For devices which only support a single report, this must be set to 0x0. + data.unshift(0) + + return data +} diff --git a/packages/usb/update-right-firmware.sh b/packages/usb/update-right-firmware.sh index 7fb73f67..207a6067 100755 --- a/packages/usb/update-right-firmware.sh +++ b/packages/usb/update-right-firmware.sh @@ -1,8 +1,8 @@ #!/bin/sh set -e # fail the script if a command fails -./jump-to-bootloader.js -blhost --usb 0x15a2,0x0073 flash-security-disable 0403020108070605 -blhost --usb 0x15a2,0x0073 flash-erase-region 0xc000 475136 -blhost --usb 0x15a2,0x0073 flash-image uhk-right.srec -blhost --usb 0x15a2,0x0073 reset +node jump-to-bootloader.js +./blhost --usb 0x15a2,0x0073 flash-security-disable 0403020108070605 +./blhost --usb 0x15a2,0x0073 flash-erase-region 0xc000 475136 +./blhost --usb 0x15a2,0x0073 flash-image uhk-right.srec +./blhost --usb 0x15a2,0x0073 reset diff --git a/packages/usb/wait-until-i2c-dies.js b/packages/usb/wait-until-i2c-dies.js index 058f118f..ae1f893c 100755 --- a/packages/usb/wait-until-i2c-dies.js +++ b/packages/usb/wait-until-i2c-dies.js @@ -1,30 +1,19 @@ #!/usr/bin/env node -let uhk = require('./uhk'); -let [endpointIn, endpointOut] = uhk.getUsbEndpoints(); -var arg = process.argv[2] || ''; +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); let lastWatchdogCounter = -1; function monitorI2c() { - var payload = new Buffer([uhk.usbCommands.readDebugInfo]); + const payload = new Buffer([uhk.usbCommands.readDebugInfo]); // console.log('Sending ', uhk.bufferToString(payload)); - endpointOut.transfer(payload, function(err) { - if (err) { - console.error("USB error: %s", err); - process.exit(1); - } - endpointIn.transfer(64, function(err2, receivedBuffer) { - if (err2) { - console.error("USB error: %s", err2); - process.exit(2); - } - let watchdogCounter = (receivedBuffer[1] << 0) + (receivedBuffer[2] << 8) + (receivedBuffer[3] << 16) + (receivedBuffer[4] << 24); - if (watchdogCounter === lastWatchdogCounter) { - process.exit(0); - } -// console.log('Received', watchdogCounter); - setTimeout(monitorI2c, 100) - }) - }); + device.write(uhk.getTransferData(payload)); + device.write([64]); + const receivedBuffer = Buffer.from(device.readSync()); + const watchdogCounter = (receivedBuffer[1] << 0) + (receivedBuffer[2] << 8) + (receivedBuffer[3] << 16) + (receivedBuffer[4] << 24); + if (watchdogCounter === lastWatchdogCounter) { + process.exit(0); + } + setTimeout(monitorI2c, 100) } monitorI2c(); diff --git a/packages/usb/write-config.js b/packages/usb/write-config.js index f5ec7dd5..9a671fb0 100755 --- a/packages/usb/write-config.js +++ b/packages/usb/write-config.js @@ -1,39 +1,38 @@ #!/usr/bin/env node -let fs = require('fs'); -let uhk = require('./uhk'); +const fs = require('fs'); +const uhk = require('./uhk'); +const device = uhk.getUhkDevice(); const chunkSize = 60; -let isHardwareConfig = process.argv[2] === 'h'; -let configTypeString = isHardwareConfig ? 'hardware' : 'user'; -let isFirstSend = true; -let isFirstReceive = true; +const isHardwareConfig = process.argv[2] === 'h'; +const configTypeString = isHardwareConfig ? 'hardware' : 'user'; let configSize; let offset = 0; let configBuffer = fs.readFileSync(`${configTypeString}-config.write`); let chunkSizeToRead; -uhk.sendUsbPacketsByCallback(() => { - if (isFirstSend) { - isFirstSend = false; - return new Buffer([uhk.usbCommands.getProperty, isHardwareConfig ? uhk.systemPropertyIds.hardwareConfigSize : uhk.systemPropertyIds.userConfigSize]); - } else { - chunkSizeToRead = Math.min(chunkSize, configSize - offset) - let usbCommand = isHardwareConfig ? uhk.usbCommands.writeHardwareConfig : uhk.usbCommands.writeUserConfig; - let buffer = Buffer.concat([ - new Buffer([usbCommand, chunkSizeToRead, offset & 0xff, offset >> 8]), - configBuffer.slice(offset, offset+chunkSizeToRead) - ]); - let bufferOrNull = offset >= configSize ? null : buffer; - offset += chunkSizeToRead; - return bufferOrNull; - } -}); +const payload = new Buffer([ + uhk.usbCommands.getProperty, + isHardwareConfig + ? uhk.systemPropertyIds.hardwareConfigSize + : uhk.systemPropertyIds.userConfigSize + ]); -uhk.registerReceiveCallback((buffer) => { - if (isFirstReceive) { - isFirstReceive = false; - configSize = buffer[1] + (buffer[2]<<8); - console.log(`${configTypeString}configSize:`, configSize); - } -}); +device.write(uhk.getTransferData(payload)); +let buffer = Buffer.from(device.readSync()); +configSize = buffer[1] + (buffer[2]<<8); +console.log(`${configTypeString}configSize:`, configSize); + +while (offset < configSize){ + const usbCommand = isHardwareConfig ? uhk.usbCommands.writeHardwareConfig : uhk.usbCommands.writeUserConfig; + chunkSizeToRead = Math.min(chunkSize, configSize - offset); + buffer = Buffer.concat([ + new Buffer([usbCommand, chunkSizeToRead, offset & 0xff, offset >> 8]), + configBuffer.slice(offset, offset+chunkSizeToRead) + ]); + console.log('write-config-chunk:', uhk.bufferToString(buffer)); + device.write(uhk.getTransferData(buffer)); + device.readSync(); + offset += chunkSizeToRead; +} diff --git a/packages/usb/write-eeprom.js b/packages/usb/write-eeprom.js deleted file mode 100755 index 24264dfb..00000000 --- a/packages/usb/write-eeprom.js +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node -let uhk = require('./uhk'); - -let programName = process.argv[1]; -let arg = process.argv[2] || ''; - -if (arg.length === 0) { - console.log(`Usage: ${programName} [string to be written to the EEPROM]`); - process.exit(1); -} - -uhk.sendUsbPacket(Buffer.concat([new Buffer([uhk.usbCommands.writeEeprom, arg.length+2, 0x00, 0x00]), new Buffer(arg, 'utf8')]))