diff --git a/lib/tessel.js b/lib/tessel.js index 1d6428b..a0550a9 100644 --- a/lib/tessel.js +++ b/lib/tessel.js @@ -410,7 +410,7 @@ function Tessel(options) { } }, - serialPorts: {} + uart: {} }; priv.set(this, state); @@ -419,9 +419,6 @@ function Tessel(options) { // board connection status in the terminal (debug=true) this.name = `Tessel 2 (${os.hostname()})`; - // Used to store serialport objects? - this.serialPorts = {}; - // Used by Johnny-Five for analog sensor components // with explicit analog voltage sensitive algorithms this.aref = 3.3; @@ -754,14 +751,9 @@ Tessel.prototype.serialConfig = function(options) { throw new Error("serialConfig expected `options` object"); } - // Default to Port A's UART (user facing name is "A") - if (!options.bus) { - // Maybe they called it "port"? Let's allow that. - if (options.port) { - options.bus = options.port; - } else { - options.bus = "A"; - } + if (options.portId === undefined || + (options.portId !== A && options.portId !== B)) { + throw new Error("serialConfig expected `options.portId` (A or B)"); } var baud = options.baud || 57600; @@ -769,40 +761,46 @@ Tessel.prototype.serialConfig = function(options) { var parity = options.parity || "none"; var stopBits = options.stopBits || 1; - var port = tessel.port[options.bus]; - state.serialPorts[options.bus] = new port.UART({ "baudrate": baud, "dataBits": dataBits, "parity": parity, "stopBits": stopBits }); + state.uart[options.portId] = new tessel.port[options.portId].UART({ + // "baud" is the property that was already defined by Firmata + baudrate: baud, + dataBits: dataBits, + parity: parity, + stopBits: stopBits + }); }; Tessel.prototype.serialWrite = function(portId, inBytes) { var state = priv.get(this); - var data = []; - for (var i = 0, len = inBytes.length; i < len; i++) { - data.push(inBytes[i] & 0x007F); - data.push((inBytes[i] >> 7) & 0x007F); + if (!Array.isArray(inBytes)) { + inBytes = [inBytes]; } - if (state.serialPorts[options.bus]) { - state.serialPorts[options.bus].write(new Buffer(inBytes)); + if (state.uart[portId]) { + state.uart[portId].write(new Buffer(inBytes)); } }; Tessel.prototype.serialRead = function(portId, maxBytesToRead, callback) { var state = priv.get(this); - if (state.serialPorts[portId]) { - state.serialPorts[portId].on("data", callback); + if (state.uart[portId]) { + state.uart[portId].on("data", callback); } }; Tessel.prototype.serialStop = function(portId) { var state = priv.get(this); - if (state.serialPorts[portId]) { - state.serialPorts[portId].removeAllListeners("data"); + if (state.uart[portId]) { + state.uart[portId].removeAllListeners("data"); } }; Tessel.prototype.serialClose = function(portId) { - // Has no analog in Tessel Serial + var state = priv.get(this); + if (state.uart[portId]) { + state.uart[portId].disable(); + } }; Tessel.prototype.serialFlush = function(portId) { diff --git a/test/tessel.js b/test/tessel.js index 1621a98..2a1cd3a 100644 --- a/test/tessel.js +++ b/test/tessel.js @@ -1331,3 +1331,129 @@ exports["Tessel.prototype.setSamplingInterval"] = { test.done(); } }; + + +exports["Tessel.prototype.serialConfig"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + + this.a = this.sandbox.stub(tessel.port.A, "UART"); + this.b = this.sandbox.stub(tessel.port.B, "UART"); + + this.tessel = new Tessel(); + done(); + }, + tearDown: function(done) { + this.sandbox.restore(); + Tessel.purge(); + done(); + }, + validWithDefaults: function(test) { + test.expect(4); + var configA = { + portId: "A", + }; + var configB = { + portId: "B", + }; + + this.tessel.serialConfig(configA); + this.tessel.serialConfig(configB); + + test.equal(this.a.callCount, 1); + test.equal(this.b.callCount, 1); + + test.deepEqual(this.a.lastCall.args[0], { + baudrate: 57600, + dataBits: 8, + parity: "none", + stopBits: 1, + }); + test.deepEqual(this.b.lastCall.args[0], { + baudrate: 57600, + dataBits: 8, + parity: "none", + stopBits: 1, + }); + + test.done(); + }, + + validWithExplicit: function(test) { + test.expect(4); + + var configA = { + portId: "A", + baud: 9600, + dataBits: 8, + parity: "none", + stopBits: 1, + }; + var configB = { + portId: "B", + baud: 9600, + dataBits: 8, + parity: "none", + stopBits: 1, + }; + + this.tessel.serialConfig(configA); + this.tessel.serialConfig(configB); + + test.equal(this.a.callCount, 1); + test.equal(this.b.callCount, 1); + + test.deepEqual(this.a.lastCall.args[0], { + baudrate: 9600, + dataBits: 8, + parity: "none", + stopBits: 1, + }); + + test.deepEqual(this.b.lastCall.args[0], { + baudrate: 9600, + dataBits: 8, + parity: "none", + stopBits: 1, + }); + + test.done(); + }, + + invalidMissingOptions: function(test) { + test.expect(3); + + test.throws(() => { + this.tessel.serialConfig(); + }); + test.equal(this.a.callCount, 0); + test.equal(this.b.callCount, 0); + + test.done(); + }, + + invalidMissingPortId: function(test) { + test.expect(3); + + test.throws(() => { + this.tessel.serialConfig({}); + }); + test.equal(this.a.callCount, 0); + test.equal(this.b.callCount, 0); + + test.done(); + }, + + invalidPortId: function(test) { + test.expect(3); + + test.throws(() => { + this.tessel.serialConfig({ portId: "jdfnkjdfnb" }); + }); + test.equal(this.a.callCount, 0); + test.equal(this.b.callCount, 0); + + test.done(); + }, + +};