From d4f5a1fc9d2a8c063110a471d511de411c0dc989 Mon Sep 17 00:00:00 2001 From: Patrick Gunderson Date: Wed, 18 Jan 2017 11:32:10 -0800 Subject: [PATCH] moved to a new repo --- .DS_Store | Bin 0 -> 6148 bytes .eslintrc.json | 297 +++++++++++ .gitignore | 2 + .jsbeautifyrc | 33 ++ .travis.yml | 6 + README.md | 74 +++ examples/i2cLedMatrix.js | 46 ++ examples/led.js | 9 + examples/magnetometer.js | 68 +++ lib/omega2.js | 382 +++++++++++++ package.json | 35 ++ test/beaglebone.js | 1088 ++++++++++++++++++++++++++++++++++++++ test/not-implemented.js | 32 ++ 13 files changed, 2072 insertions(+) create mode 100644 .DS_Store create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .jsbeautifyrc create mode 100644 .travis.yml create mode 100644 README.md create mode 100644 examples/i2cLedMatrix.js create mode 100644 examples/led.js create mode 100644 examples/magnetometer.js create mode 100644 lib/omega2.js create mode 100644 package.json create mode 100644 test/beaglebone.js create mode 100644 test/not-implemented.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 -1 ) { + if ( pin.value !== 1 ) { + pin.value = 1; + changed = true; + } + } else if ( data.indexOf( ': 0' ) > -1 ) { + if ( pin.value !== 0 ) { + pin.value = 0; + changed = true; + } + } + if ( changed ) { + // TODO: Emit event + } + } ); + CP.on( 'exit', function() { + handler( {} ); + } ); + + return this; +}; + +Omega2.prototype.digitalWrite = function( pin, value ) { + if ( this.pins[pin].mode !== this.MODES.OUTPUT ) { + this.pinMode( pin, this.MODES.OUTPUT ); + } + + this.pins[pin].value = value; + CP.spawn( 'fast-gpio', [ 'set', pin, value] ); + + return this; +}; + +Omega2.prototype.servoWrite = function( pin, value, frequency ) { + console.error( 'Omega2 doesn\'t support servo mode' ); + + return this; +}; + +Omega2.prototype.i2cConfig = function( options ) { + var delay; + + if ( typeof options === 'number' ) { + delay = options; + } else { + if ( typeof options === 'object' && options !== null ) { + delay = options.delay; + } + } + + delay = delay || 0; + + if ( _i2cBus === undefined ) { + _i2cBus = i2c.openSync( 1 ); + _i2cDelay = delay; + } + + return this; +}; + +// this method supports both +// i2cWrite(address, register, inBytes) +// and +// i2cWrite(address, inBytes) +Omega2.prototype.i2cWrite = function( address, cmdRegOrData, inBytes ) { + /** + * cmdRegOrData: + * [... arbitrary bytes] + * + * or + * + * cmdRegOrData, inBytes: + * command [, ...] + * + */ + var buffer; + + this.i2cConfig( ); + + // If i2cWrite was used for an i2cWriteReg call... + if (arguments.length === 3 && !Array.isArray( cmdRegOrData ) && !Array.isArray( inBytes )) { + return this.i2cWriteReg( address, cmdRegOrData, inBytes ); + } + + // Fix arguments if called with Firmata.js API + if ( arguments.length === 2 ) { + if (Array.isArray( cmdRegOrData )) { + inBytes = cmdRegOrData.slice( ); + cmdRegOrData = inBytes.shift( ); + } else { + inBytes = [ ]; + } + } + + buffer = new Buffer([ cmdRegOrData ].concat( inBytes )); + + // Only write if bytes provided + if ( buffer.length ) { + _i2cBus.i2cWriteSync( address, buffer.length, buffer ); + } + + return this; +}; + +Omega2.prototype.i2cWriteReg = function( address, register, value ) { + this.i2cConfig( ); + + _i2cBus.writeByteSync( address, register, value ); + + return this; +}; + +Omega2.prototype._i2cRead = function( continuous, address, register, bytesToRead, callback ) { + var data; + var event = 'I2C-reply' + address + '-'; + + this.i2cConfig( ); + + // Fix arguments if called with Firmata.js API + if ( arguments.length === 4 && typeof register === 'number' && typeof bytesToRead === 'function' ) { + callback = bytesToRead; + bytesToRead = register; + register = null; + } + + data = new Buffer( bytesToRead ); + + callback = typeof callback === 'function' + ? callback + : function( ) {}; + + event += register !== null + ? register + : 0; + + setTimeout( function read( ) { + var afterRead = function( err, bytesRead, buffer ) { + if ( err ) { + return this.emit( 'error', err ); + } + + // Convert buffer to Array before emit + this.emit(event, [ ].slice.call( buffer )); + + if ( continuous ) { + setTimeout( read.bind( this ), _i2cDelay ); + } + }.bind( this ); + + this.once( event, callback ); + + if ( register !== null ) { + _i2cBus.readI2cBlock( address, register, bytesToRead, data, afterRead ); + } else { + _i2cBus.i2cRead( address, bytesToRead, data, afterRead ); + } + }.bind( this ), _i2cDelay); + + return this; +}; + +// this method supports both +// i2cRead(address, register, bytesToRead, handler) +// and +// i2cRead(address, bytesToRead, handler) +Omega2.prototype.i2cRead = function( address, register, bytesToRead, handler ) { + return this + ._i2cRead + .apply(this, [ true ].concat([ ].slice.call( arguments ))); +}; + +// this method supports both +// i2cReadOnce(address, register, bytesToRead, handler) +// and +// i2cReadOnce(address, bytesToRead, handler) +Omega2.prototype.i2cReadOnce = function( address, register, bytesToRead, handler ) { + return this + ._i2cRead + .apply(this, [ false ].concat([ ].slice.call( arguments ))); +}; + +// Necessary for Firmata.js compatibility. +Omega2.prototype.sendI2CConfig = Omega2.prototype.i2cConfig; +Omega2.prototype.sendI2CReadRequest = Omega2.prototype.i2cReadOnce; +Omega2.prototype.sendI2CWriteRequest = Omega2.prototype.i2cWrite; + +// Not Supported +[ + 'pulseIn', + 'pulseOut', + 'queryPinState', + '_sendOneWireRequest', + '_sendOneWireSearch', + 'sendOneWireWriteAndRead', + 'sendOneWireDelay', + 'sendOneWireDelay', + 'sendOneWireReset', + 'sendOneWireRead', + 'sendOneWireSearch', + 'sendOneWireAlarmsSearch', + 'sendOneWireConfig', + 'stepperConfig', + 'stepperStep' + ].forEach( function( method ) { + Omega2.prototype[method] = function( ) { + throw method + ' is not yet implemented.'; + }; + +}); + +module.exports = Omega2; diff --git a/package.json b/package.json new file mode 100644 index 0000000..55086db --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "omega2-io", + "version": "0.0.2", + "description": "Onion Omega2 & Omega2+ IO Plugin for Johnny-Five", + "main": "lib/omega2", + "scripts": { + "test": "" + }, + "repository": { + "type": "git", + "url": "https://github.com/gunderson/omega2-io" + }, + "keywords": [ + "firmata", + "omega2", + "omega", + "onion", + "johnny-five" + ], + "author": "Patrick Gunderson ", + "license": "MIT", + "bugs": { + "url": "https://github.com/gunderson/omega2-io/issues" + }, + "homepage": "https://github.com/gunderson/omega2-io", + "devDependencies": { + "johnny-five": "^0.10.6", + "nodeunit": "^0.9.0", + "rewire": "^2.1.0", + "sinon": "^1.10.3" + }, + "dependencies": { + "i2c-bus": "^0.11.2" + } +} diff --git a/test/beaglebone.js b/test/beaglebone.js new file mode 100644 index 0000000..41149ab --- /dev/null +++ b/test/beaglebone.js @@ -0,0 +1,1088 @@ +var rewire = require("rewire"); +var BeagleBone = rewire("../lib/beaglebone"); +var Emitter = require("events").EventEmitter; +var sinon = require("sinon"); +var b = require('bonescript'); + +var bStub = { + pinMode: function(pin, mode) {}, + digitalRead: function(pin, handler) { + handler(null); + }, + analogRead: function(pin, handler) { + handler(null); + }, + digitalWrite: function(pin, value) {}, + analogWrite: function(pin, value) {}, + map: b.map +}; + +// Stub for the four i2c-bus methods used by beaglebone-io +var i2cBusStub = { + i2cWriteSync: function(addr, length, buffer) {}, + writeByteSync: function (addr, cmd, byte) {}, + readI2cBlock: function (addr, cmd, length, buffer, cb) {}, + i2cRead: function(addr, length, buffer, cb) {} +}; + +BeagleBone.__set__("b", bStub); +BeagleBone.__set__("_i2cBus", i2cBusStub); + +function restore(target) { + for (var prop in target) { + if (typeof target[prop].restore === "function") { + target[prop].restore(); + } + } +} + +exports["BeagleBone"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.beaglebone = new BeagleBone(); + this.proto = {}; + + this.proto.functions = [{ + name: "analogRead" + }, { + name: "analogWrite" + }, { + name: "pwmWrite" + }, { + name: "digitalRead" + }, { + name: "digitalWrite" + }, { + name: "servoWrite" + }, { + name: "i2cConfig" + }, { + name: "i2cWrite" + }, { + name: "i2cWriteReg" + }, { + name: "i2cRead" + }, { + name: "i2cReadOnce" + }, { + name: "sendI2CWriteRequest" + }, { + name: "sendI2CConfig" + }, { + name: "sendI2CReadRequest" + }]; + + this.proto.objects = [{ + name: "MODES" + }]; + + this.proto.numbers = [{ + name: "HIGH" + }, { + name: "LOW" + }]; + + this.instance = [{ + name: "pins" + }, { + name: "analogPins" + }]; + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + done(); + }, + + shape: function(test) { + test.expect( + this.proto.functions.length + + this.proto.objects.length + + this.proto.numbers.length + + this.instance.length + ); + + this.proto.functions.forEach(function(method) { + test.equal(typeof this.beaglebone[method.name], "function"); + }, this); + + this.proto.objects.forEach(function(method) { + test.equal(typeof this.beaglebone[method.name], "object"); + }, this); + + this.proto.numbers.forEach(function(method) { + test.equal(typeof this.beaglebone[method.name], "number"); + }, this); + + this.instance.forEach(function(property) { + test.notEqual(typeof this.beaglebone[property.name], "undefined"); + }, this); + + test.done(); + }, + + readonly: function(test) { + test.expect(7); + + test.equal(this.beaglebone.HIGH, 1); + + test.throws(function() { + this.beaglebone.HIGH = 42; + }); + + test.equal(this.beaglebone.LOW, 0); + + test.throws(function() { + this.beaglebone.LOW = 42; + }); + + test.deepEqual(this.beaglebone.MODES, { + INPUT: 0, + OUTPUT: 1, + ANALOG: 2, + PWM: 3, + SERVO: 4 + }); + + test.throws(function() { + this.beaglebone.MODES.INPUT = 42; + }); + + test.throws(function() { + this.beaglebone.MODES = 42; + }); + + test.done(); + }, + + emitter: function(test) { + test.expect(1); + + test.ok(this.beaglebone instanceof Emitter); + + test.done(); + }, + + connected: function(test) { + test.expect(1); + + this.beaglebone.on("connect", function() { + test.ok(true); + + test.done(); + }); + }, + + ready: function(test) { + test.expect(1); + + this.beaglebone.on("ready", function() { + test.ok(true); + + test.done(); + }); + }, + + normalize: function(test) { + test.expect(4); + + test.equal(2, this.beaglebone.normalize("2")); + test.equal(2, this.beaglebone.normalize("P8_9")); + test.equal(13, this.beaglebone.normalize("USR3")); + test.equal(14, this.beaglebone.normalize("A0")); + + test.done(); + } +}; + +exports["BeagleBone.prototype.analogRead"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P9_39"; + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + this.beaglebone.removeAllListeners("analog-read-A0"); + this.beaglebone.removeAllListeners("digital-read-9"); + + done(); + }, + + correctMode: function(test) { + test.expect(1); + + this.beaglebone.analogRead("A0", function() {}); + test.equal(this.beaglebone.pins[14].mode, 2); + + test.done(); + }, + + analogPin: function(test) { + test.expect(2); + + var value = 1024; + + this.analogRead = sinon.stub(bStub, "analogRead", function(pin, cb) { + var result = { + value: 1 + }; + + cb(result); + }); + + var handler = function(data) { + test.equal(data, value); + + test.done(); + }; + + this.beaglebone.analogRead(0, handler); + + test.equal(this.beaglebone.pins[14].mode, 2); + }, + + port: function(test) { + test.expect(1); + + var port = this.port; + + this.analogRead = sinon.stub(bStub, "analogRead", function(pin, cb) { + test.equal(port, pin); + + test.done(); + }); + + var handler = function(data) {}; + + this.beaglebone.analogRead("A0", handler); + }, + + handler: function(test) { + test.expect(1); + + var value = 1024; + + this.analogRead = sinon.stub(bStub, "analogRead", function(pin, cb) { + var result = { + value: 1 + }; + + cb(result); + }); + + var handler = function(data) { + test.equal(data, value); + test.done(); + }; + + this.beaglebone.analogRead("A0", handler); + }, + + event: function(test) { + test.expect(1); + + var value = 1024; + var event = "analog-read-0"; + + this.analogRead = sinon.stub(bStub, "analogRead", function(pin, cb) { + var result = { + value: 1 + }; + + cb(result); + }); + + this.beaglebone.once(event, function(data) { + test.equal(data, value); + test.done(); + }); + + var handler = function(data) {}; + this.beaglebone.analogRead("A0", handler); + } +}; + +exports["BeagleBone.prototype.digitalRead"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P8_13"; + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + this.beaglebone.removeAllListeners("analog-read-A0"); + this.beaglebone.removeAllListeners("digital-read-3"); + + done(); + }, + + correctMode: function(test) { + test.expect(1); + + this.beaglebone.digitalRead(3, function() {}); + test.equal(this.beaglebone.pins[3].mode, 0); + + test.done(); + }, + + port: function(test) { + test.expect(1); + + var port = this.port; + + this.digitalRead = sinon.stub(bStub, "digitalRead", function(pin, cb) { + test.equal(port, pin); + test.done(); + }); + + var handler = function(data) {}; + this.beaglebone.digitalRead(3, handler); + }, + + handler: function(test) { + test.expect(1); + + var value = 1; + + this.digitalRead = sinon.stub(bStub, "digitalRead", function(pin, cb) { + var result = { + value: 1 + }; + cb(result); + }); + + var handler = function(data) { + test.equal(data, value); + test.done(); + }; + + this.beaglebone.digitalRead(3, handler); + }, + + event: function(test) { + test.expect(1); + + var value = 1; + var event = "digital-read-3"; + + this.digitalRead = sinon.stub(bStub, "digitalRead", function(pin, cb) { + var result = { + value: 1 + }; + + cb(result); + }); + + + this.beaglebone.once(event, function(data) { + test.equal(data, value); + test.done(); + }); + + var handler = function(data) {}; + this.beaglebone.digitalRead(3, handler); + } +}; + +exports["BeagleBone.prototype.analogWrite"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P9_39"; + this.analogWrite = sinon.spy(BeagleBone.prototype, "analogWrite"); + this.beaglebone = new BeagleBone(); + + done(); + }, + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + mode: function(test) { + test.expect(3); + + var value = 255; + + // Set pin to INPUT... + this.beaglebone.pinMode("A0", 0); + test.equal(this.beaglebone.pins[14].mode, 0); + + // Writing to a pin should change its mode to 1 + this.beaglebone.analogWrite("A0", value); + test.equal(this.beaglebone.pins[14].mode, 3); + test.equal(this.beaglebone.pins[14].isPwm, true); + + test.done(); + }, + + write: function(test) { + test.expect(2); + + var value = 255; + + this.beaglebone.analogWrite("A0", value); + test.ok(this.analogWrite.calledOnce); + test.deepEqual(this.analogWrite.firstCall.args, ["A0", value]); + + test.done(); + }, + + stored: function(test) { + test.expect(1); + + var value = 255; + this.beaglebone.analogWrite("A0", value); + test.equal(this.beaglebone.pins[14].value, value); + + test.done(); + } +}; + +exports["BeagleBone.prototype.pwmWrite"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P9_39"; + this.pwmWrite = sinon.spy(BeagleBone.prototype, "pwmWrite"); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + mode: function(test) { + test.expect(3); + + var value = 255; + + // Set pin to INPUT... + this.beaglebone.pinMode("A0", 0); + test.equal(this.beaglebone.pins[14].mode, 0); + + // Writing to a pin should change its mode to 1 + this.beaglebone.pwmWrite("A0", value); + test.equal(this.beaglebone.pins[14].mode, 3); + test.equal(this.beaglebone.pins[14].isPwm, true); + + test.done(); + }, + + write: function(test) { + test.expect(2); + + var value = 255; + + this.beaglebone.pwmWrite("A0", value); + test.ok(this.pwmWrite.calledOnce); + test.deepEqual(this.pwmWrite.firstCall.args, ["A0", value]); + + test.done(); + }, + + stored: function(test) { + test.expect(1); + + var value = 255; + this.beaglebone.pwmWrite("A0", value); + test.equal(this.beaglebone.pins[14].value, value); + + test.done(); + } +}; + +exports["BeagleBone.prototype.digitalWrite"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P8_13"; + this.digitalWrite = sinon.spy(BeagleBone.prototype, "digitalWrite"); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + mode: function(test) { + test.expect(3); + + var value = 1; + + // Set pin to INPUT... + this.beaglebone.pinMode(3, 0); + test.equal(this.beaglebone.pins[3].mode, 0); + + // Writing to a pin should change its mode to 1 + this.beaglebone.digitalWrite(3, value); + test.equal(this.beaglebone.pins[3].mode, 1); + test.equal(this.beaglebone.pins[3].isPwm, false); + + test.done(); + }, + + write: function(test) { + test.expect(2); + + var value = 1; + this.beaglebone.digitalWrite(3, value); + test.ok(this.digitalWrite.calledOnce); + test.deepEqual(this.digitalWrite.firstCall.args, [3, value]); + + test.done(); + }, + + stored: function(test) { + test.expect(1); + + var value = 1; + this.beaglebone.digitalWrite(3, value); + test.equal(this.beaglebone.pins[3].value, value); + + test.done(); + } +}; + +exports["BeagleBone.prototype.servoWrite"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.port = "P8_13"; + this.servoWrite = sinon.spy(BeagleBone.prototype, "servoWrite"); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + mode: function(test) { + test.expect(2); + + var value = 180; + + // Set pin to INPUT... + this.beaglebone.pinMode("3", 0); + test.equal(this.beaglebone.pins[3].mode, 0); + + // Writing to a pin should change its mode to 4 + this.beaglebone.servoWrite("3", value); + test.equal(this.beaglebone.pins[3].mode, 4); + + test.done(); + }, + + write: function(test) { + test.expect(2); + + var value = 90; + + this.beaglebone.servoWrite("3", value); + test.ok(this.servoWrite.calledOnce); + test.deepEqual(this.servoWrite.firstCall.args, ["3", value]); + + test.done(); + }, + + stored: function(test) { + test.expect(2); + + var value = 180; + + this.beaglebone.servoWrite("3", value); + test.equal(this.beaglebone.pins[3].value, value); + test.equal(); + + test.done(); + } +}; + +exports["BeagleBone.prototype.pinMode (analog)"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + restore(this); + + done(); + }, + + analogOut: function(test) { + test.expect(1); + + this.beaglebone.pinMode("A0", 1); + test.equal(this.beaglebone.pins[14].mode, 1); + + test.done(); + }, + + analogIn: function(test) { + test.expect(2); + + this.beaglebone.pinMode("A0", 0); + test.equal(this.beaglebone.pins[14].mode, 0); + + this.beaglebone.pinMode(0, 2); + test.equal(this.beaglebone.pins[14].mode, 2); + + test.done(); + } +}; + +exports["BeagleBone.prototype.pinMode (digital)"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + restore(this); + + done(); + }, + digitalOut: function(test) { + test.expect(1); + + this.beaglebone.pinMode(3, 1); + test.equal(this.beaglebone.pins[3].mode, 1); + + test.done(); + }, + + digitalIn: function(test) { + test.expect(1); + + this.beaglebone.pinMode(3, 0); + test.equal(this.beaglebone.pins[3].mode, 0); + + test.done(); + } +}; + +exports["BeagleBone.prototype.i2cWrite"] = { + setUp: function(done) { + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + writeBytesToRegister: function(test) { + test.expect(3); + + this.i2cWriteSync = sinon.stub(i2cBusStub, "i2cWriteSync", function(addr, length, buffer) { + test.equal(addr, 33); + test.equal(length, 5); + test.deepEqual(buffer, Buffer([8, 3, 4, 5, 6])); + }); + + this.beaglebone.i2cWrite(33, 8, [3, 4, 5, 6]); + + test.done(); + }, + + writeBytes: function(test) { + test.expect(3); + + this.i2cWriteSync = sinon.stub(i2cBusStub, "i2cWriteSync", function(addr, length, buffer) { + test.equal(addr, 33); + test.equal(length, 4); + test.deepEqual(buffer, Buffer([3, 4, 5, 6])); + }); + + this.beaglebone.i2cWrite(33, [3, 4, 5, 6]); + + test.done(); + }, + + writeByteToRegister: function(test) { + test.expect(3); + + this.i2cWriteReg = sinon.stub(i2cBusStub, "writeByteSync", function(addr, cmd, byte) { + test.equal(addr, 44); + test.equal(cmd, 7); + test.equal(byte, 12); + }); + + this.beaglebone.i2cWrite(44, 7, 12); + + test.done(); + } +}; + +exports["BeagleBone.prototype.i2cWriteReg"] = { + setUp: function(done) { + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + i2cWriteReg: function(test) { + test.expect(3); + + this.writeByteSync = sinon.stub(i2cBusStub, "writeByteSync", function(addr, cmd, byte) { + test.equal(addr, 44); + test.equal(cmd, 7); + test.equal(byte, 12); + }); + + this.beaglebone.i2cWriteReg(44, 7, 12); + + test.done(); + } +}; + +exports["BeagleBone.prototype.i2cRead"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + this.beaglebone.removeAllListeners("I2C-reply55-2"); + this.beaglebone.removeAllListeners("I2C-reply77-0"); + + done(); + }, + + // i2cRead 4 bytes starting at register 2 from device at address 55. + // If all goes well, i2cRead will delegate the work to + // i2cBus#readI2cBlock and pass the bytes read to a callback. + readFromRegisterWithCallback: function(test) { + // expect 10 as there should be two iterations of continuous i2cRead + test.expect(10); + + this.readI2cBlock = sinon.stub(i2cBusStub, "readI2cBlock", function(addr, cmd, length, buffer, cb) { + test.equal(addr, 55); + test.equal(cmd, 2); + test.equal(length, 4); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([10, 20, 30, 40]).copy(buffer); + + cb(null, 4, buffer); + + if (this.readI2cBlock.callCount === 2) { + test.done(); + } else { + this.clock.tick(1); + } + }.bind(this)); + + this.beaglebone.i2cRead(55, 2, 4, function(bytesRead) { + test.deepEqual(bytesRead, [10, 20, 30, 40]); + }.bind(this)); + + this.clock.tick(1); + }, + + // i2cRead 4 bytes starting at register 2 from device at address 55. + // If all goes well, i2cRead will delegate the work to + // i2cBus#readI2cBlock and pass the bytes read to an event handler. + readFromRegisterWithEvent: function(test) { + // Locally on a BeagleBone test.expect(10) will allways work as expected. + // On faster machines, sometimes only 9 asserts are detected, not 10. + // Commented out as a workaround for the moment. + // expect 10 as there should be two iterations of continuous i2cRead + //test.expect(10); + + this.readI2cBlock = sinon.stub(i2cBusStub, "readI2cBlock", function(addr, cmd, length, buffer, cb) { + test.equal(addr, 55); + test.equal(cmd, 2); + test.equal(length, 4); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([10, 20, 30, 40]).copy(buffer); + + cb(null, 4, buffer); + + if (this.readI2cBlock.callCount === 2) { + test.done(); + } else { + this.clock.tick(1); + } + }.bind(this)); + + this.beaglebone.on("I2C-reply55-2", function(bytesRead) { + test.deepEqual(bytesRead, [10, 20, 30, 40]); + }); + + this.beaglebone.i2cRead(55, 2, 4, function(bytesRead) {}); + + this.clock.tick(1); + }, + + // Read 6 bytes from device at address 77. + // If all goes well, i2cRead will delegate the work to + // i2cBus#i2cRead and pass the bytes read to a callback. + readWithCallback: function(test) { + // expect 8 as there should be two iterations of continuous i2cRead + test.expect(8); + + this.i2cRead = sinon.stub(i2cBusStub, "i2cRead", function(addr, length, buffer, cb) { + test.equal(addr, 77); + test.equal(length, 6); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([6, 5, 4, 3, 2, 1]).copy(buffer); + + cb(null, 6, buffer); + + if (this.i2cRead.callCount === 2) { + test.done(); + } else { + this.clock.tick(1); + } + }.bind(this)); + + this.beaglebone.i2cRead(77, 6, function(bytesRead) { + test.deepEqual(bytesRead, [6, 5, 4, 3, 2, 1]); + }); + + this.clock.tick(1); + }, + + // Read 6 bytes from device at address 77. + // If all goes well, i2cRead will delegate the work to + // i2cBus#i2cRead and pass the bytes read to an event handler. + readWithEvent: function(test) { + // Locally on a BeagleBone test.expect(8) will allways work as expected. + // On faster machines, sometimes only 7 asserts are detected, not 8. + // Commented out as a workaround for the moment. + // expect 8 as there should be two iterations of continuous i2cRead + //test.expect(8); + + this.i2cRead = sinon.stub(i2cBusStub, "i2cRead", function(addr, length, buffer, cb) { + test.equal(addr, 77); + test.equal(length, 6); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([6, 5, 4, 3, 2, 1]).copy(buffer); + + cb(null, 6, buffer); + + if (this.i2cRead.callCount === 2) { + test.done(); + } else { + this.clock.tick(1); + } + }.bind(this)); + + this.beaglebone.on("I2C-reply77-0", function(bytesRead) { + test.deepEqual(bytesRead, [6, 5, 4, 3, 2, 1]); + }); + + this.beaglebone.i2cRead(77, 6, function() {}); + + this.clock.tick(1); + } +}; + +exports["BeagleBone.prototype.i2cReadOnce"] = { + setUp: function(done) { + this.clock = sinon.useFakeTimers(); + this.beaglebone = new BeagleBone(); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + this.beaglebone.removeAllListeners("I2C-reply55-2"); + this.beaglebone.removeAllListeners("I2C-reply77-0"); + + done(); + }, + + // Read 4 bytes starting at register 2 from device at address 55. + // If all goes well, i2cReadOnce will delegate the work to + // i2cBus#readI2cBlock and pass the bytes read to a callback. + readFromRegisterWithCallback: function(test) { + test.expect(6); + + this.readI2cBlock = sinon.stub(i2cBusStub, "readI2cBlock", function(addr, cmd, length, buffer, cb) { + test.equal(addr, 55); + test.equal(cmd, 2); + test.equal(length, 4); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([10, 20, 30, 40]).copy(buffer); + + cb(null, 4, buffer); + }); + + this.beaglebone.i2cReadOnce(55, 2, 4, function(bytesRead) { + test.ok(this.readI2cBlock.calledOnce); + test.deepEqual(bytesRead, [10, 20, 30, 40]); + + test.done(); + }.bind(this)); + + this.clock.tick(1); + }, + + // Read 4 bytes starting at register 2 from device at address 55. + // If all goes well, i2cReadOnce will delegate the work to + // i2cBus#readI2cBlock and pass the bytes read to an event handler. + readFromRegisterWithEvent: function(test) { + test.expect(6); + + this.readI2cBlock = sinon.stub(i2cBusStub, "readI2cBlock", function(addr, cmd, length, buffer, cb) { + test.equal(addr, 55); + test.equal(cmd, 2); + test.equal(length, 4); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([10, 20, 30, 40]).copy(buffer); + + cb(null, 4, buffer); + }); + + this.beaglebone.once("I2C-reply55-2", function(bytesRead) { + test.ok(this.readI2cBlock.calledOnce); + test.deepEqual(bytesRead, [10, 20, 30, 40]); + + test.done(); + }.bind(this)); + + this.beaglebone.i2cReadOnce(55, 2, 4, function(bytesRead) {}); + + this.clock.tick(1); + }, + + // Read 6 bytes from device at address 77. + // If all goes well, i2cReadOnce will delegate the work to + // i2cBus#i2cRead and pass the bytes read to a callback. + readWithCallback: function(test) { + test.expect(5); + + this.i2cRead = sinon.stub(i2cBusStub, "i2cRead", function(addr, length, buffer, cb) { + test.equal(addr, 77); + test.equal(length, 6); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([6, 5, 4, 3, 2, 1]).copy(buffer); + + cb(null, 6, buffer); + }); + + this.beaglebone.i2cReadOnce(77, 6, function(bytesRead) { + test.ok(this.i2cRead.calledOnce); + test.deepEqual(bytesRead, [6, 5, 4, 3, 2, 1]); + + test.done(); + }.bind(this)); + + this.clock.tick(1); + }, + + // Read 6 bytes from device at address 77. + // If all goes well, i2cReadOnce will delegate the work to + // i2cBus#i2cRead and pass the bytes read to an event handler. + readWithEvent: function(test) { + test.expect(5); + + this.i2cRead = sinon.stub(i2cBusStub, "i2cRead", function(addr, length, buffer, cb) { + test.equal(addr, 77); + test.equal(length, 6); + test.ok(Buffer.isBuffer(buffer)); + + Buffer([6, 5, 4, 3, 2, 1]).copy(buffer); + + cb(null, 6, buffer); + }); + + this.beaglebone.once("I2C-reply77-0", function(bytesRead) { + test.ok(this.i2cRead.calledOnce); + test.deepEqual(bytesRead, [6, 5, 4, 3, 2, 1]); + + test.done(); + }.bind(this)); + + this.beaglebone.i2cReadOnce(77, 6, function() {}); + + this.clock.tick(1); + } +}; + +exports["BeagleBone.prototype.i2cConfig"] = { + setUp: function(done) { + this.beaglebone = new BeagleBone(); + this.i2cConfig = sinon.spy(this.beaglebone, "i2cConfig"); + + done(); + }, + + tearDown: function(done) { + BeagleBone.reset(); + restore(this); + + done(); + }, + + i2cConfig: function(test) { + test.expect(2); + + this.beaglebone.i2cConfig(500); + + test.ok(this.i2cConfig.calledOnce); + test.ok(this.i2cConfig.firstCall.args, 500); + + test.done(); + } +}; + diff --git a/test/not-implemented.js b/test/not-implemented.js new file mode 100644 index 0000000..a20085b --- /dev/null +++ b/test/not-implemented.js @@ -0,0 +1,32 @@ +var BeagleBone = require("../lib/beaglebone"); +var sinon = require("sinon"); +var title = "Not Implemented"; + +exports[title] = {}; + +[ + "pulseIn", + "pulseOut", + "queryPinState", + "_sendOneWireRequest", + "_sendOneWireSearch", + "sendOneWireWriteAndRead", + "sendOneWireDelay", + "sendOneWireDelay", + "sendOneWireReset", + "sendOneWireRead", + "sendOneWireSearch", + "sendOneWireAlarmsSearch", + "sendOneWireConfig", + "stepperConfig", + "stepperStep" +].forEach(function(method) { + exports[title][method] = function(test) { + test.expect(2); + test.ok(BeagleBone.prototype[method]); + test.throws(function() { + BeagleBone.prototype[method].call({}); + }); + test.done(); + }; +});