diff --git a/usb/blink-test-led.js b/usb/blink-test-led.js index bef0fcf6..13bf8868 100755 --- a/usb/blink-test-led.js +++ b/usb/blink-test-led.js @@ -2,10 +2,11 @@ 'use strict'; var usb = require('usb'); +var util = require('./util'); var vid = 0x16d3; var pid = 0x05ea; -var test_led_command_id = 1; +var test_led_command_id = 2; var device = usb.findByIds(vid, pid); device.open(); @@ -22,13 +23,19 @@ var endpointOut = usbInterface.endpoints[1]; var state = 1; setInterval(function() { - console.log('Sending ', state); state = state ? 0 : 1 - console.log(state) + console.log('Sending ', state); endpointOut.transfer(new Buffer([test_led_command_id, state]), 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', util.bufferToString(receivedBuffer)); + }) }); }, 500) diff --git a/usb/pulse-leds.js b/usb/pulse-leds.js new file mode 100755 index 00000000..737fd1a2 --- /dev/null +++ b/usb/pulse-leds.js @@ -0,0 +1,214 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var ledMatrixSize = 144; +var ledCountToUpdatePerCommand = ledMatrixSize / 3; +var writeLedDriverCommandId = 3; +var leftLedDriverAddress = 0b1110100; +var rightLedDriverAddress = 0b1110111; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; + +var state = 1; + +var ledsLeft = new Buffer(ledMatrixSize); +var ledsRight = new Buffer(ledMatrixSize); +ledsLeft.fill(0xff) +ledsRight.fill(0xff) + +var ledIndex = 0; +var matrixId = 0; + +var initLedCommands = [ + [ // only enable the LEDs that are actually in the matrix + writeLedDriverCommandId, + leftLedDriverAddress, + 19, + 0, + 0b00000001, 0b00111111, + 0, 0b00111111, + 0, 0b00111111, + 0, 0b00011111, + 0, 0b00011111, + 0, 0b00011111, + 0, 0b00011111, + 0, 0b00011111, + 0, 0b00011111, + ], + [ // only enable the LEDs that are actually in the matrix + writeLedDriverCommandId, + rightLedDriverAddress, + 19, + 0, + 0b00000001, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + ], + [writeLedDriverCommandId, leftLedDriverAddress, 2, 0xfd, 0x0b], // switch to function page + [writeLedDriverCommandId, leftLedDriverAddress, 2, 0xc2, 0xff], // enable the ghost image prevention bit + [writeLedDriverCommandId, leftLedDriverAddress, 2, 0xfd, 0x00], // switch to page 0 +] + +var ledCommandId = 0; + +function initLeds() { + var ledCommand = initLedCommands[ledCommandId++]; + console.log('initLeds', ledCommand); + var buffer = new Buffer(ledCommand); + + endpointOut.transfer(buffer, function(err) { + if (err) { + console.error("USB error: %s", err); + process.exit(1); + } + if (ledCommandId < initLedCommands.length) { + initLeds(); + } else { + updateLeds(); + } + }); +} + +function updateLeds() { +// console.log('update') + var buffer = Buffer.concat([ + new Buffer([ + writeLedDriverCommandId, + matrixId ? rightLedDriverAddress : leftLedDriverAddress, + ledCountToUpdatePerCommand, + 0x24 + ledIndex + ]), + (matrixId ? ledsRight : ledsLeft).slice(ledIndex, ledIndex + ledCountToUpdatePerCommand) + ]); + console.log('iter: '+letterIdx+' out:', util.bufferToString(buffer)) + endpointOut.transfer(buffer, function(err) { + if (err) { + console.error("USB error: %s", err); + process.exit(1); + } +// console.log('update success') + endpointIn.transfer(64, function(err2, receivedBuffer) { + if (err2) { + console.error("USB error: %s", err2); + process.exit(2); + } +// console.log('Received', util.bufferToString(receivedBuffer)); + + ledIndex += ledCountToUpdatePerCommand; + if (ledIndex >= ledMatrixSize) { + ledIndex = 0; + matrixId = matrixId ? 0 : 1; + } + + updateLeds(); + }) + }); +} + +initLeds(); + +var letterIdx = 0; + +var 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], +} + +var iconLedsToLedMatrix = [0x08, 0x09, 0x0a]; +var layerLedsToLedMatrix = [0x0d, 0x1d, 0x2d]; + +var 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 (var i=0; i= digitsAndLetters.length) { + letterIdx = 0; + } + layerLedIdx = ++layerLedIdx % layerLedsToLedMatrix.length; +}, 200); diff --git a/usb/read-eeprom.js b/usb/read-eeprom.js new file mode 100755 index 00000000..48d48b0f --- /dev/null +++ b/usb/read-eeprom.js @@ -0,0 +1,37 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var readEepromCommandId = 6; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; + +var payload = new Buffer([readEepromCommandId, 63, 0x00, 0x00]); +console.log('Sending ', util.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', util.bufferToString(receivedBuffer)); + }) +}); diff --git a/usb/read-iso-jumper.js b/usb/read-iso-jumper.js new file mode 100755 index 00000000..91ae11ba --- /dev/null +++ b/usb/read-iso-jumper.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var readIsoJumperCommandId = 9; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; + +function readLedJumper() { + var payload = new Buffer([readIsoJumperCommandId]); + console.log('Sending ', util.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', util.bufferToString(receivedBuffer)); + var isIso = receivedBuffer[1] === 0; + console.log('ISO jumper is ' + (isIso ? 'closed' : 'open') + ' so the detected layout is ' + (isIso ? 'ISO' : 'ANSI')); + console.log('Restart the UHK after switching the switch for the change to take effect!'); + }) + }); +} + +readLedJumper(); diff --git a/usb/read-led-jumper.js b/usb/read-led-jumper.js new file mode 100755 index 00000000..fd442a7d --- /dev/null +++ b/usb/read-led-jumper.js @@ -0,0 +1,44 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var readLedJumperCommandId = 8; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; + +function readLedJumper() { + var payload = new Buffer([readLedJumperCommandId]); + console.log('Sending ', util.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', util.bufferToString(receivedBuffer)); + var isLedJumperOn = receivedBuffer[1] === 0; + console.log('LED jumper is ' + (isLedJumperOn ? 'on' : 'off')) + setTimeout(readLedJumper, 500) + }) + }); +} + +readLedJumper(); diff --git a/usb/read-merge-sensor.js b/usb/read-merge-sensor.js new file mode 100755 index 00000000..56ffe182 --- /dev/null +++ b/usb/read-merge-sensor.js @@ -0,0 +1,46 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var readMergeSensorCommandId = 7; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; +var arg = process.argv[2] || ''; + + +function readMergeSensor() { + var payload = new Buffer([readMergeSensorCommandId]); + console.log('Sending ', util.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', util.bufferToString(receivedBuffer)); + setTimeout(readMergeSensor, 500) + var areHalvesMerged = receivedBuffer[1] === 1; + console.log('The keyboards halves are ' + (areHalvesMerged ? 'merged' : 'split')) + }) + }); +} + +readMergeSensor(); diff --git a/usb/util.js b/usb/util.js new file mode 100755 index 00000000..b9da78e0 --- /dev/null +++ b/usb/util.js @@ -0,0 +1,13 @@ +exports = module.exports = { + bufferToString: function(buffer) { + var str = ''; + for (var i = 0; i < buffer.length; i++) { + var hex = buffer[i].toString(16) + ' '; + if (hex.length <= 2) { + hex = '0' + hex; + } + str += hex; + }; + return str; + } +} diff --git a/usb/write-eeprom.js b/usb/write-eeprom.js new file mode 100755 index 00000000..8db73e8e --- /dev/null +++ b/usb/write-eeprom.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node +'use strict'; + +var usb = require('usb'); +var util = require('./util'); + +var vid = 0x16d3; +var pid = 0x05ea; +var writeEepromCommandId = 5; + +var device = usb.findByIds(vid, pid); +device.open(); + +var usbInterface = device.interface(0); +if (usbInterface.isKernelDriverActive()) { + usbInterface.detachKernelDriver(); +} +usbInterface.claim(); + +var endpointIn = usbInterface.endpoints[0]; +var endpointOut = usbInterface.endpoints[1]; +var arg = process.argv[2] || ''; + +if (arg.length === 0) { + console.log('Gotta specify a string to be written to the EEPROM as the argument of this script'); + process.exit(1); +} + +var payload = Buffer.concat([new Buffer([writeEepromCommandId, arg.length+2, 0x00, 0x00]), new Buffer(arg, 'utf8')]); +console.log('Sending ', util.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', util.bufferToString(receivedBuffer)); + }) +});