0.1.21 added/improved chip configuration now have two more intPullup and intPullupOneInt
fixed issue with forEach by replacing with for loop on pins configuration so it would do in correct order. added some logging on commands filemaster
parent
f6b40be73b
commit
be1787fa45
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@uci/mcp",
|
"name": "@uci/mcp",
|
||||||
"main": "src",
|
"main": "src",
|
||||||
"version": "0.1.20",
|
"version": "0.1.21",
|
||||||
"description": "Classes and Helper Functions for using the MCP chip on I2C Bus",
|
"description": "Classes and Helper Functions for using the MCP chip on I2C Bus",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"relays": "node -r esm examples/relays",
|
"relays": "node -r esm examples/relays",
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import * as _ from '@uci-utils/byte'
|
import * as _ from '@uci-utils/byte'
|
||||||
import { CHIP, PIN } from './config'
|
import { CHIP, PIN } from './config'
|
||||||
|
import logger from '@uci-utils/logger'
|
||||||
|
|
||||||
|
let log = {file:'/src/commands.js', package:'@uci/mcp'}
|
||||||
|
|
||||||
|
|
||||||
// TODO add uci debug logging
|
// TODO add uci debug logging
|
||||||
|
|
||||||
|
@ -21,12 +25,15 @@ export default {
|
||||||
let byte = _.byteFormat(setting.val, { in: setting.fmt, out: 'DEC' })
|
let byte = _.byteFormat(setting.val, { in: setting.fmt, out: 'DEC' })
|
||||||
if (byte < 128) byte += 128 // make sure BANK=1 remains on
|
if (byte < 128) byte += 128 // make sure BANK=1 remains on
|
||||||
let reg = this.chip17 ? 0x0A : 0x05
|
let reg = this.chip17 ? 0x0A : 0x05
|
||||||
// console.log(this.chip17, reg, this.id, this.address)
|
log.debug ({msg:'writing chip configuration', chip17:this.chip17, register:reg, id:this.id, address:this.address})
|
||||||
bus = await this.bus.write(reg,byte)
|
bus = await this.bus.write(reg,byte)
|
||||||
if (bus.error) return bus
|
if (bus.error) return bus
|
||||||
bus = await this.bus.read(0x05)
|
bus = await this.bus.read(0x05)
|
||||||
if (bus.error) return bus
|
if (bus.error) return bus
|
||||||
return { cmd:'reply', response:_.byteFormat(bus.response,{in:'DEC',out:'STR'}) }
|
if (!this.chip17) bus.response = bus.response - 127
|
||||||
|
let res = _.byteFormat(bus.response,{in:'DEC',out:'STR'})
|
||||||
|
if (res !== setting.val) return { cmd:'reply', error:`chip configuration failed ${res} != ${setting.val} (${cfg})`}
|
||||||
|
return { cmd:'reply', response:res }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -43,6 +50,7 @@ export default {
|
||||||
else cfg = PIN.cfgset[packet.cfg]
|
else cfg = PIN.cfgset[packet.cfg]
|
||||||
for(let name of Object.keys(PIN.setting)) {
|
for(let name of Object.keys(PIN.setting)) {
|
||||||
let op = cfg[name] ? 'on' : 'off'
|
let op = cfg[name] ? 'on' : 'off'
|
||||||
|
console.log({msg:'setting pin register', operation:op, registerName:name, resgisterNum:PIN.setting[name]})
|
||||||
let busreply = await this.pin._state(packet,op,PIN.setting[name])
|
let busreply = await this.pin._state(packet,op,PIN.setting[name])
|
||||||
if (busreply.error) return busreply
|
if (busreply.error) return busreply
|
||||||
reply.status[name] = busreply.status
|
reply.status[name] = busreply.status
|
||||||
|
@ -71,7 +79,7 @@ export default {
|
||||||
},
|
},
|
||||||
_state: async function(packet,op,reg){
|
_state: async function(packet,op,reg){
|
||||||
reg = (reg!==undefined)? reg : PIN.cmd.gpio
|
reg = (reg!==undefined)? reg : PIN.cmd.gpio
|
||||||
// console.log('_state change request', op, reg, packet)
|
log.debug({msg:'_state change request', operation:op, register:reg, packet:packet})
|
||||||
let reply = { cmd:'reply'}
|
let reply = { cmd:'reply'}
|
||||||
let pins = parsePins(packet.pins)
|
let pins = parsePins(packet.pins)
|
||||||
let state = new _.Byte()
|
let state = new _.Byte()
|
||||||
|
@ -83,6 +91,7 @@ export default {
|
||||||
bus = await this.bus.read(sreg(reg,packet.port))
|
bus = await this.bus.read(sreg(reg,packet.port))
|
||||||
if (bus.error) return bus
|
if (bus.error) return bus
|
||||||
state.value = bus.response
|
state.value = bus.response
|
||||||
|
log.debug({msg:'after setting pin state', prev:state.prv, new:state.value})
|
||||||
reply.status = state.bwOp(pins.value,'check',{in:'PLC', out:'PLC'})
|
reply.status = state.bwOp(pins.value,'check',{in:'PLC', out:'PLC'})
|
||||||
return reply
|
return reply
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,9 +9,17 @@ export const CHIP = {
|
||||||
val: '10100010', // Split Banks port A + 0x10 = Port B,(ignored by 23008), Sequential operation disabled, active high=pulldown
|
val: '10100010', // Split Banks port A + 0x10 = Port B,(ignored by 23008), Sequential operation disabled, active high=pulldown
|
||||||
fmt: 'STR'
|
fmt: 'STR'
|
||||||
},
|
},
|
||||||
oneint: {
|
oneInt: {
|
||||||
val: '11100100', // same as default execpt interupt pins of port A and B are connected
|
val: '11100100', // same as default execpt interupt pins of port A and B are connected
|
||||||
fmt: 'STR'
|
fmt: 'STR'
|
||||||
|
},
|
||||||
|
intPullup: {
|
||||||
|
val: '10100000', // same as default execpt interupt pins active=low means pullup (high and go low on trip)
|
||||||
|
fmt: 'STR'
|
||||||
|
},
|
||||||
|
intPullupOneInt: {
|
||||||
|
val: '10100000', // same as intPullup and oneInt combined
|
||||||
|
fmt: 'STR'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ class MCP230XX extends Device {
|
||||||
id: this.id
|
id: this.id
|
||||||
})
|
})
|
||||||
this.chip17 = opts.chip17
|
this.chip17 = opts.chip17
|
||||||
|
this.chipCfg = opts.chipCfg || 'default'
|
||||||
this.commands = this.bindFuncs(commands)
|
this.commands = this.bindFuncs(commands)
|
||||||
this.addNamespace('commands', 's') // allow access to commands via socket/server
|
this.addNamespace('commands', 's') // allow access to commands via socket/server
|
||||||
this.pin = this.commands.pin // add a simplier reference for local access
|
this.pin = this.commands.pin // add a simplier reference for local access
|
||||||
|
@ -23,10 +24,10 @@ class MCP230XX extends Device {
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await super.init()
|
await super.init()
|
||||||
let res = await this.chipcfg({})
|
let res = await this.chipcfg({cfg:this.chipCfg})
|
||||||
let cfg = this.chip17 ? '10100010' : '00100010'
|
log.fatal({msg:'unable to configure mcp chip',cfg:this.chipCfg, address:this.address})
|
||||||
if (res.response !== cfg)
|
if (res.error)
|
||||||
throw `could not configure mcp chip at ${this.address}/${this.address.toString(16)}`
|
throw `${res.error} at address ${this.address}/${this.address.toString(16)}`
|
||||||
}
|
}
|
||||||
} // end of MCP230XX Class
|
} // end of MCP230XX Class
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,23 @@ import { byteFormat } from '@uci-utils/byte'
|
||||||
import logger from '@uci-utils/logger'
|
import logger from '@uci-utils/logger'
|
||||||
let log = {}
|
let log = {}
|
||||||
|
|
||||||
|
log = logger({
|
||||||
|
file: 'src/mcp230xxi.js',
|
||||||
|
class: 'MCP230XXi',
|
||||||
|
name: 'mcp-interrupt',
|
||||||
|
})
|
||||||
|
|
||||||
// if opts.iport not set then will be generated based on pin number
|
// if opts.iport not set then will be generated based on pin number
|
||||||
|
|
||||||
class MCP230XXi extends MCP230XX {
|
class MCP230XXi extends MCP230XX {
|
||||||
constructor(pins, options={}) {
|
constructor(pins, options={}) {
|
||||||
if (!Array.isArray(pins)) { options = pins; pins = options.interrupt.pins} // if pins sent via .interrupt.pins
|
|
||||||
|
|
||||||
let opts = Object.assign({},options) // don't allow options to mutate
|
if (!Array.isArray(pins)) { options = pins; pins = options.interrupt.pins} // if pins sent via .interrupt.pins
|
||||||
if (opts.interrupt) delete opts.interrupt.pins // if .interrupt is passed then .pins must be removed
|
let opts = Object.assign({},options) // don't allow passed options to mutate
|
||||||
delete opts.sockets // .sockets is used by uci base so clear it was sent by mistake
|
if (opts.interrupt) delete opts.interrupt.pins // if .interrupt was passed then .pins must be removed
|
||||||
// console.log('options as ready for mcp',pins, opts)
|
delete opts.sockets // .sockets is used by uci base so clear it if was used by enduser and sent by mistake
|
||||||
|
log.debug({msg:'passed options before setting',options:opts})
|
||||||
|
|
||||||
// if iport or ipath is set then all interrupts have a single consolidating socket
|
// if iport or ipath is set then all interrupts have a single consolidating socket
|
||||||
if (typeof opts.iport === 'number' || opts.ipath) {
|
if (typeof opts.iport === 'number' || opts.ipath) {
|
||||||
if (typeof opts.iport === 'number') {
|
if (typeof opts.iport === 'number') {
|
||||||
|
@ -29,11 +36,11 @@ class MCP230XXi extends MCP230XX {
|
||||||
// otherwise each pin will have its own socket so make a client for each
|
// otherwise each pin will have its own socket so make a client for each
|
||||||
pins.forEach((pin, index) => {
|
pins.forEach((pin, index) => {
|
||||||
let ipin = 'i' + pin
|
let ipin = 'i' + pin
|
||||||
opts[ipin] = opts[pin] || opts.interrupt || {}
|
opts[ipin] = opts[pin] || Object.assign({},opts.interrupt) || {}
|
||||||
if (index === 1) opts[ipin].mport = opts[ipin].mport || 'B'
|
if (index === 1) opts[ipin].mport = opts[ipin].mport || 'B'
|
||||||
delete opts[pin]
|
delete opts[pin]
|
||||||
if (opts[ipin].host) {
|
if (opts[ipin].host) {
|
||||||
opts[ipin].port = opts[ipin].port ? opts[ipin].port + +pin : 9000 + +pin
|
opts[ipin].port = opts[ipin].port ? opts[ipin].port + +pin : 9000 + parseInt(pin)
|
||||||
opts[ipin].host = opts[ipin].host
|
opts[ipin].host = opts[ipin].host
|
||||||
opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + ipin + '#c>t'
|
opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + ipin + '#c>t'
|
||||||
}
|
}
|
||||||
|
@ -45,16 +52,16 @@ class MCP230XXi extends MCP230XX {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
super(opts)
|
super(opts)
|
||||||
|
|
||||||
log = logger({
|
log = logger({
|
||||||
file: 'src/mcp230xxi.js',
|
file: 'src/mcp230xxi.js',
|
||||||
class: 'MCP230XXi',
|
class: 'MCP230XXi',
|
||||||
name: 'mcp',
|
name: 'mcp-interrupt',
|
||||||
id: this.id
|
id: this.id
|
||||||
})
|
})
|
||||||
log.info(
|
|
||||||
{ opts: opts },
|
log.info({ opts: opts, msg:'mcp interrupt options after calling super() on base'})
|
||||||
'mcp interrupt options after calling super() on base'
|
|
||||||
)
|
|
||||||
pins.forEach(pin => {
|
pins.forEach(pin => {
|
||||||
this[pin] = opts['i' + pin] || {}
|
this[pin] = opts['i' + pin] || {}
|
||||||
})
|
})
|
||||||
|
@ -68,7 +75,7 @@ class MCP230XXi extends MCP230XX {
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await super.init()
|
await super.init()
|
||||||
this.pins.forEach(async pin => {
|
for (let pin of this.pins) {
|
||||||
let cfg = {
|
let cfg = {
|
||||||
port: this[pin].mport || 'A',
|
port: this[pin].mport || 'A',
|
||||||
pins: this[pin].pins || 'all',
|
pins: this[pin].pins || 'all',
|
||||||
|
@ -76,16 +83,16 @@ class MCP230XXi extends MCP230XX {
|
||||||
}
|
}
|
||||||
// this will set default type to internal pullup, only need to to change indivial pins to external if desired
|
// this will set default type to internal pullup, only need to to change indivial pins to external if desired
|
||||||
await this.pin.cfg(cfg)
|
await this.pin.cfg(cfg)
|
||||||
// shouldn't need this as reset is pushed upon connection to interrupt socket
|
log.info('initial resetting of mcp interrupt port for corresponding sbc gpio pin')
|
||||||
// log.info('initial resetting of mcp interrupt port for corresponding sbc gpio pin')
|
await this._reset(this[pin].mport)
|
||||||
// await this._reset(this[pin].mport)
|
|
||||||
this.ready = true
|
this.ready = true
|
||||||
})
|
}
|
||||||
|
|
||||||
this.on('interrupt', function(details) {
|
this.on('interrupt', function(details) {
|
||||||
details.id = this.id
|
details.id = this.id
|
||||||
if (!this._interruptProcess) {
|
if (!this._interruptProcess) {
|
||||||
console.log('----default interrupt processor for mcp instance----')
|
console.log('----default interrupt processor for mcp instance----')
|
||||||
|
console.log('create your own function and register it with .interruptProcess(function)')
|
||||||
console.log(this.id)
|
console.log(this.id)
|
||||||
console.dir(details)
|
console.dir(details)
|
||||||
} else this._interruptProcess(details)
|
} else this._interruptProcess(details)
|
||||||
|
@ -94,7 +101,7 @@ class MCP230XXi extends MCP230XX {
|
||||||
|
|
||||||
async _reset(port) {
|
async _reset(port) {
|
||||||
// local non-packet hidden command
|
// local non-packet hidden command
|
||||||
console.log(`resetting interrupt for port ${port || 'A'},${this.id} arg ${port !== 'B' ? 0x08 : 0x1}`)
|
log.debug(`resetting interrupt for port ${port || 'A'},${this.id} arg ${port !== 'B' ? 0x08 : 0x18}`)
|
||||||
return await this.bus.read(port !== 'B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register
|
return await this.bus.read(port !== 'B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,15 +128,14 @@ const ipincommands = {
|
||||||
// given a gpio interrupt then push a packet with cmd: 'pin.interrupt.find' and pin: the gpio pin number
|
// given a gpio interrupt then push a packet with cmd: 'pin.interrupt.find' and pin: the gpio pin number
|
||||||
find: async function(inter) {
|
find: async function(inter) {
|
||||||
// inter is a UCI packet
|
// inter is a UCI packet
|
||||||
console.log('packet from interrupt to interpret',inter)
|
|
||||||
if (this.ready) {
|
if (this.ready) {
|
||||||
// protects tripped interrupt before it's fully initialized, or interrupt requests arriving before porcessing is complete
|
// protects tripped interrupt before it's fully initialized, or interrupt requests arriving before porcessing is complete
|
||||||
this.ready = false
|
this.ready = false
|
||||||
log.info({ packet: inter }, 'finding mcp pin which caused interrupt')
|
log.debug({msg:'raw packet from interrupt, will now find the pin that caused interrupt', inter:inter})
|
||||||
let packet = { pins: 'all', reg: 'intf' }
|
let packet = { pins: 'all', reg: 'intf' }
|
||||||
packet.port = inter.port || this[inter.pin].mport || 'A'
|
packet.port = inter.port || this[inter.pin].mport || 'A'
|
||||||
let res = await this.pin.status(packet)
|
let res = await this.pin.status(packet)
|
||||||
log.info('found pin now resetting mcp port interrupt')
|
|
||||||
if (!res.status) return { error: 'no pin associated with interrupt' }
|
if (!res.status) return { error: 'no pin associated with interrupt' }
|
||||||
let pin = byteFormat(res.status.port, { in: 'ARY', out: 'PLC' })
|
let pin = byteFormat(res.status.port, { in: 'ARY', out: 'PLC' })
|
||||||
res.pin = pin[0]
|
res.pin = pin[0]
|
||||||
|
@ -143,6 +149,7 @@ const ipincommands = {
|
||||||
res.inter = inter.pin
|
res.inter = inter.pin
|
||||||
delete res.status
|
delete res.status
|
||||||
this.emit('interrupt', res)
|
this.emit('interrupt', res)
|
||||||
|
log.debug({msg:'found pin now resetting mcp port interrupt', response:res})
|
||||||
}
|
}
|
||||||
await this._reset(packet.port)
|
await this._reset(packet.port)
|
||||||
this.ready = true
|
this.ready = true
|
||||||
|
|
Loading…
Reference in New Issue