FIRST commit of socket/packet based i2cbus with separate class bus-packet
It is functional and working with example bus to run (on rpi) and various clientsmaster
parent
c737a29368
commit
a2844cc313
|
@ -1,11 +1,17 @@
|
|||
module.exports = {
|
||||
"ecmaFeatures": {
|
||||
"modules": true,
|
||||
"spread" : true,
|
||||
"restParams" : true
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
"ecmaVersion": 2017,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"@std/esm": "cjs"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
*.log
|
||||
*.sock
|
||||
/node_modules/
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* i2c bus with both unix and tcp socket using defaults. For TCP that is host OS name and port 8080
|
||||
*
|
||||
*/
|
||||
|
||||
import Bus from '../src/bus-packet'
|
||||
|
||||
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||
|
||||
;
|
||||
(async () => {
|
||||
|
||||
// let i2cbus = new Bus({id:'i2c-bus', log:true})
|
||||
let i2cbus = new Bus({id:'i2c-bus', sockets:'us,ts', log:true})
|
||||
|
||||
await i2cbus.init()
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||
})
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* A tcp customer/client to talk with the i2c bus and scan the bus for devices
|
||||
*
|
||||
*/
|
||||
|
||||
const PATH = '/opt/uci/uci-base/src/unix.sock'
|
||||
|
||||
import Base from '../../uci-base/src/base'
|
||||
// import Base from '@uci/base'
|
||||
|
||||
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||
;
|
||||
(async () => {
|
||||
|
||||
let relays = new Base({sockets:'uc', path:PATH, log:true})
|
||||
|
||||
relays.reply = function (packet) {
|
||||
// console.log(packet.bus)
|
||||
console.log('response from relays',packet.bus.func, packet.bus.args.cmd, packet.bus.response)
|
||||
}
|
||||
await relays.init()
|
||||
console.log('=============sending============')
|
||||
let packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd: 0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 0, byte:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 9, byte:255}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:9}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
await delay(1000)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 9, byte:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:9}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
|
||||
await delay(1000)
|
||||
process.kill(process.pid, 'SIGTERM')
|
||||
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||
})
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* i2c bus unix socket and client in one for demo
|
||||
*
|
||||
*/
|
||||
|
||||
import Bus from '../src/bus-packet'
|
||||
|
||||
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||
;
|
||||
(async () => {
|
||||
|
||||
let i2cbus = new Bus({id:'i2c-bus', sockets:'us,uc'})
|
||||
|
||||
i2cbus.reply = function (packet) {
|
||||
console.log('==== response from i2cbus =>',packet.bus.response)
|
||||
}
|
||||
|
||||
await i2cbus.init()
|
||||
console.log('=============sending============')
|
||||
let packet = {cmd:'rw', bus:{func:'scan'} }
|
||||
console.dir(packet)
|
||||
await i2cbus.send(packet)
|
||||
|
||||
await delay(1000)
|
||||
process.kill(process.pid, 'SIGTERM')
|
||||
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||
})
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* A tcp customer/client to talk with the i2c bus and scan the bus for devices
|
||||
*
|
||||
*/
|
||||
|
||||
const HOST = 'sbc'
|
||||
|
||||
import Base from '../../uci-base/src/base'
|
||||
// import Base from '@uci/base'
|
||||
|
||||
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||
;
|
||||
(async () => {
|
||||
|
||||
let relays = new Base({id:'tcp-i2c-client', sockets:'tc', host:HOST, log:true})
|
||||
|
||||
relays.reply = function (packet) {
|
||||
// console.log(packet.bus)
|
||||
console.log('response from relays',packet.bus.func, packet.bus.args.cmd, packet.bus.response)
|
||||
}
|
||||
await relays.init()
|
||||
console.log('=============sending============')
|
||||
let packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd: 0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 0, byte:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 9, byte:255}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:9}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
await delay(1000)
|
||||
packet = {cmd:'rw', bus:{func:'write', args:{address:39,cmd: 9, byte:0}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
packet = {cmd:'rw', bus:{func:'read', args:{address:39 ,cmd:9}} }
|
||||
console.dir(packet.bus)
|
||||
await relays.send(packet)
|
||||
|
||||
await delay(1000)
|
||||
process.kill(process.pid, 'SIGTERM')
|
||||
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||
})
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* A tcp customer/client to talk with the i2c bus and scan the bus for devices
|
||||
*
|
||||
*/
|
||||
|
||||
const HOST = 'sbc'
|
||||
|
||||
|
||||
|
||||
const delay = time => new Promise(res=>setTimeout(()=>res(),time))
|
||||
;
|
||||
(async () => {
|
||||
|
||||
let scanner = new Base({id:'tcp-i2c-client', sockets:'tc', host:HOST})
|
||||
|
||||
scanner.reply = function (packet) {
|
||||
let addresses = packet.bus.response.map(device => {
|
||||
return device.toString(16)})
|
||||
console.log(packet)
|
||||
console.log('==== device hex addreses on i2cbus ===\n',addresses)
|
||||
}
|
||||
await scanner.init()
|
||||
console.log('=============sending============')
|
||||
let packet = {cmd:'rw', bus:{func:'scan'} }
|
||||
console.dir(packet)
|
||||
await scanner.send(packet)
|
||||
|
||||
await delay(3000)
|
||||
process.kill(process.pid, 'SIGTERM')
|
||||
|
||||
|
||||
})().catch(err => {
|
||||
console.error('FATAL: UNABLE TO START SYSTEM!\n',err)
|
||||
})
|
8
index.js
8
index.js
|
@ -1,8 +0,0 @@
|
|||
let opts = {
|
||||
dirname: __dirname + '/src',
|
||||
// http://stackoverflow.com/questions/2078915/a-regular-expression-to-exclude-a-word-string
|
||||
filter: /^(?!index)([^\.].*)\.js?$/,
|
||||
recursive: false,
|
||||
merge: true // remove or comment to have each file in /lib be a prop/key in library...see node-require-all
|
||||
}
|
||||
module.exports = require('@uci/require-all')(opts)
|
20
package.json
20
package.json
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"name": "@uci/i2c",
|
||||
"version": "0.1.1",
|
||||
"description": "Bus and Device Classes for I2C Interfacing",
|
||||
"main": "index.js",
|
||||
"name": "@uci/i2c-bus",
|
||||
"version": "0.1.0",
|
||||
"description": "I2c Bus Classes for Communication to I2C bus via socket or direct call",
|
||||
"main": "src/bus",
|
||||
"scripts": {
|
||||
"testw": "./node_modules/.bin/mocha --reporter list --recursive --watch",
|
||||
"test": "istanbul cover ./node_modules/.bin/_mocha test/ --report lcovonly -- -R spec --recursive && codecov || true"
|
||||
"test": "mocha -r @std/esm test/*.test.mjs",
|
||||
"testw": "mocha -r @std/esm test/*.test.mjs --watch --recurse --watch-extensions mjs",
|
||||
"testci": "istanbul cover ./node_modules/.bin/_mocha test/ --report lcovonly -- -R spec --recursive && codecov || true"
|
||||
},
|
||||
"author": "David Kebler",
|
||||
"license": "MIT",
|
||||
|
@ -23,11 +24,14 @@
|
|||
"url": "https://github.com/uCOMmandIt/i2c/issues"
|
||||
},
|
||||
"homepage": "https://github.com/uCOMmandIt/i2c#readme",
|
||||
"@std/esm": "cjs",
|
||||
"dependencies": {
|
||||
"@uci/require-all": "^2.x",
|
||||
"i2c-bus": "^1.x"
|
||||
"@uci/base": "^0.1.0",
|
||||
"i2c-bus": "^1.x",
|
||||
"pify": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@std/esm": "^0.18.0",
|
||||
"chai": "^3.5.0",
|
||||
"chai-as-promised": "^6.0.0",
|
||||
"codecov": "^1.0.1",
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
import i2c from 'i2c-bus'
|
||||
import pify from 'pify'
|
||||
// import Base from '@uci/base'
|
||||
import Base from '../../uci-base/src/base'
|
||||
|
||||
export default class Bus extends Base {
|
||||
constructor(opts) {
|
||||
opts.sockets = opts.sockets || 'us'
|
||||
super(opts)
|
||||
this.busnum = opts.busnum || 1
|
||||
this.i2cbus = i2c.open(this.busnum, () => {})
|
||||
this.funcs = bus_funcs
|
||||
// this.init = this.init.bind(this)
|
||||
}
|
||||
|
||||
async init(){
|
||||
// console.log('init', this.rw)
|
||||
await super.init()
|
||||
}
|
||||
|
||||
async rw (packet){
|
||||
// console.dir('=>',packet.bus.fusncs)
|
||||
if (!packet.bus.func) return {error: 'no i2c bus function in packet', packet: packet.bus }
|
||||
if (this.funcs[packet.bus.func]) {
|
||||
packet.bus.response = await this.funcs[packet.bus.func].bind(this)(packet.bus.args)
|
||||
packet.cmd = 'reply'
|
||||
return packet
|
||||
}
|
||||
return {error: 'no i2c bus function available for packet function', packet: packet.bus }
|
||||
}
|
||||
|
||||
} // end of Bus Packet Class
|
||||
|
||||
const bus_funcs = {
|
||||
|
||||
scan: function () { return pify(this.i2cbus.scan).bind(this.i2cbus)() },
|
||||
close: function () { return pify(this.i2cbus.close).bind(this.i2cbus)() },
|
||||
|
||||
readRaw: function (arg) {
|
||||
return pify(this.i2cbus.i2cRead).bind(this.i2cbus)(arg.address, arg.length, arg.buffer)
|
||||
},
|
||||
|
||||
writeRaw: function (arg) {
|
||||
return pify(this.i2cbus.i2cWrite).bind(this.i2cbus)(arg.address, arg.length, arg.buffer)
|
||||
},
|
||||
|
||||
read: function (arg) {
|
||||
// console.log('read: address, cmd', address, cmd)
|
||||
return pify(this.i2cbus.readByte).bind(this.i2cbus)(arg.address, arg.cmd)
|
||||
},
|
||||
|
||||
write: function (arg) {
|
||||
// console.log('write: address, cmd, byte', arg.address, arg.cmd, arg.byte)
|
||||
return pify(this.i2cbus.writeByte.bind(this.i2cbus))(arg.address, arg.cmd, arg.byte)
|
||||
},
|
||||
|
||||
read2: function (arg) {
|
||||
return pify(this.i2cbus.readWord.bind(this.i2cbus))(arg.address, arg.cmd)
|
||||
},
|
||||
|
||||
write2: function (arg) {
|
||||
return pify(this.i2cbus.writeWord.bind(this.i2cbus))(arg.address, arg.cmd, arg.bytes)
|
||||
},
|
||||
|
||||
receive: function (arg) {
|
||||
// console.log('receivebyte', address)
|
||||
return pify(this.i2cbus.receiveByte.bind(this.i2cbus))(arg.address)
|
||||
},
|
||||
|
||||
send: function (arg) {
|
||||
// console.log('sendbyte', address,byte)
|
||||
return pify(this.i2cbus.sendByte.bind(this.i2cbus))(arg.address, arg.byte)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,8 @@
|
|||
// Solely a promise wrapper module for the basic async functions of the fivdi/i2c-bus javascript bindings C API
|
||||
// https://github.com/fivdi/i2c-bus
|
||||
|
||||
'use strict'
|
||||
import i2c from 'i2c-bus'
|
||||
import pify from 'pify'
|
||||
|
||||
const i2c = require('i2c-bus'),
|
||||
pify = require('pify')
|
||||
|
||||
class Bus {
|
||||
export default class Bus {
|
||||
constructor(busnum=1) {
|
||||
this.busnum = busnum
|
||||
this.bus = i2c.open(this.busnum, () => {})
|
||||
|
@ -55,7 +51,3 @@ class Bus {
|
|||
|
||||
|
||||
} // end of Bus Class
|
||||
|
||||
module.exports = {
|
||||
Bus
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// **********************************
|
||||
|
||||
class Device {
|
||||
// bus is i2c-bus bus object
|
||||
constructor(bus, address, opts) {
|
||||
this.bus = bus
|
||||
this.address = address
|
||||
if (opts) {
|
||||
this.id = opts.id // must be unique within a bus
|
||||
this.desc = opts.desc
|
||||
this.channel = opts.channel // if using TAC9546A channel number on which device is attached
|
||||
}
|
||||
}
|
||||
|
||||
async _setChannel() {
|
||||
// console.log('before set',this.address,this.id,this.channel, this.bus.getState)
|
||||
if (this.channel) {
|
||||
if (!this.bus.address) { return Promise.reject('Channel set but no mux on bus')}
|
||||
return this.bus.set(this.channel)
|
||||
}
|
||||
return Promise.resolve() // no channel for device either no mux or device is attached to mux bypass
|
||||
}
|
||||
|
||||
// for devices that need just a simple send of a byte without a register command
|
||||
async receive() {
|
||||
await this._setChannel()
|
||||
return this.bus.receive(this.address)
|
||||
}
|
||||
|
||||
async send(cmd, byte) {
|
||||
await this._setChannel()
|
||||
return this.bus.send(this.address, cmd, byte)
|
||||
}
|
||||
|
||||
// for devices needing a buffer/stream
|
||||
async readRaw(length, buffer) {
|
||||
await this._setChannel()
|
||||
return this.bus.readRaw(this.address, length, buffer)
|
||||
}
|
||||
|
||||
async writeRaw(length, buffer) {
|
||||
await this._setChannel()
|
||||
return this.bus.writeRaw(this.address, length, buffer)
|
||||
}
|
||||
|
||||
// both cmd and byte should be a single byte as a decimal or hex
|
||||
async read(cmd) {
|
||||
await this._setChannel()
|
||||
// console.log('after set before read',this.address,this.id,this.channel,this.bus.getState)
|
||||
return this.bus.read(this.address, cmd)
|
||||
}
|
||||
|
||||
async write(cmd, byte) {
|
||||
await this._setChannel()
|
||||
// console.log('after set, before write',this.address,this.id,this.channel,this.bus.getState)
|
||||
return this.bus.write(this.address, cmd, byte)
|
||||
}
|
||||
|
||||
// for I2C devices that use a word length packackage
|
||||
async read2(cmd) {
|
||||
await this._setChannel()
|
||||
return this.bus.read2(this.address, cmd)
|
||||
}
|
||||
|
||||
async write2(cmd, bytes) {
|
||||
await this._setChannel()
|
||||
return this.bus.write2(this.address, cmd, bytes)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Device
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const chai = require('chai'),
|
||||
chaiAsPromised = require("chai-as-promised"),
|
||||
Bus = require('../lib/bus').Bus
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
let bus = new Bus()
|
||||
|
||||
// const addresses = [0x20, 0x26, 0x27]
|
||||
const addresses = []
|
||||
|
||||
describe('Bus Class - ', function () {
|
||||
|
||||
it('Can scan the bus for devices', function () {
|
||||
|
||||
return expect(bus.scan().catch(err => console.log("an error", err))).to.eventually.deep.equal(addresses)
|
||||
|
||||
})
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
import Bus from '../src/bus'
|
||||
import chai from 'chai'
|
||||
import chaiAsPromised from 'chai-as-promised'
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
let bus = new Bus()
|
||||
|
||||
const addresses = [0x25, 0x26, 0x27]
|
||||
// const addresses = []
|
||||
|
||||
describe('Bus Class - ', function () {
|
||||
|
||||
it('Can scan the bus for devices', function () {
|
||||
|
||||
return expect(bus.scan().catch(err => console.log('an error', err))).to.eventually.deep.equal(addresses)
|
||||
|
||||
})
|
||||
})
|
|
@ -1,24 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const chai = require('chai'),
|
||||
chaiAsPromised = require('chai-as-promised'),
|
||||
Bus = require('@uci/i2c').Bus,
|
||||
Device = require('../lib/device').Device
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
let bus = new Bus()
|
||||
let device = new Device(bus, 0x20)
|
||||
|
||||
describe('Device Class - ', function () {
|
||||
|
||||
let SET = 0xff
|
||||
it('Can write and read to actual device', function () {
|
||||
|
||||
device.write(0x09, SET).then(expect(device.read(0x0A)).to.eventually.equal(SET))
|
||||
.then(setTimeout(() => device.write(0x09, 0), 3000))
|
||||
.catch(err => console.log('an error', err))
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue