From 16cea2ef02176c37ba7242ea9d5e293116572d43 Mon Sep 17 00:00:00 2001 From: David Kebler Date: Tue, 31 Jul 2018 17:11:43 -0700 Subject: [PATCH] made find function more robust against user abuse like flipping switches fast and continuouly. changed the reset command to be for pushed reset request and moved old/actual reset to private function of class. Now when instance connects to interrupt socket it should get a reset command pushed. --- package.json | 4 ++-- src/mcp230xxi.js | 41 ++++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index a10745f..4434d63 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@uci/mcp", "main": "src", - "version": "0.1.8", + "version": "0.1.9", "description": "Classes and Helper Functions for using the MCP chip on I2C Bus", "scripts": { "relays": "node -r esm examples/relays", @@ -30,7 +30,7 @@ "homepage": "https://github.com/uCOMmandIt/uci-mcp#readme", "dependencies": { "@uci/i2c-device": "^0.1.4", - "@uci/logger": "0.0.3", + "@uci/logger": "0.0.4", "@uci/utils": "^0.1.1" }, "devDependencies": { diff --git a/src/mcp230xxi.js b/src/mcp230xxi.js index 7cd468e..642eb6c 100644 --- a/src/mcp230xxi.js +++ b/src/mcp230xxi.js @@ -59,8 +59,9 @@ export default class MCP230XXi extends MCP230XX { this.pins.forEach(async pin => { let cfg = {port:this[pin].mport||'A',pins:this[pin].pins||'all', cfg:this[pin].type ||'toggle_switch'} await this.pin.cfg(cfg) - log.info('resetting mcp port for corresponding gpio pin') - await this.pin.interrupt.reset(this[pin].mport) + // 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') + // await this._reset(this[pin].mport) this.ready=true }) @@ -75,36 +76,46 @@ export default class MCP230XXi extends MCP230XX { } + async _reset(port) { // local non-packet hidden command + log.info(`resetting interrupt for port ${port || 'A'},${this.id}`) + return await this.bus.read(port!=='B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register + } + interruptProcessor(func) {this._interruptProcess = func} } // end of MCP230XX Class -// commands to be added to pin command functions +// commands to be added to pin packet command functions const ipincommands= { interrupt: { - reset: async function (port) { - log.info(`resetting interrupt for port ${port || 'A'},${this.id}`) - return await this.bus.read(port!=='B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register + reset: async function (packet) { + log.info({packet:packet},`'socket has push requested a reset of mcp interrupt port for gpio pin ${packet.pin}`) + let port = this[packet.pin].mport || 'A' + await this._reset(port) }, // given a gpio interrupt then push a packet with cmd: 'pin.interrupt.find' and pin: the gpio pin number - find: async function (inter) { // inter is a hash packet - if(this.ready){ // protects tripped interrupt before it's fully initialized and reset + find: async function (inter) { // inter is a UCI packet + if(this.ready){ // protects tripped interrupt before it's fully initialized, or interrupt requests arriving before porcessing is complete + this.ready = false log.info({packet:inter},'finding mcp pin which caused interrupt') let packet = {pins:'all',reg:'intf'} packet.port = inter.port || this[inter.pin].mport || 'A' let res = await this.pin.status(packet) log.info('found pin now resetting mcp port interrupt') - await this.pin.interrupt.reset(packet.port) if (!res.status) return {error:'no pin associated with interrupt'} let pin = byteFormat(res.status.port, { in: 'ARY', out: 'PLC' }) res.pin = pin[0] packet.pins = pin[0] packet.reg = null - res.state = (await this.pin.status(packet)).status.pins[0][1] - res.port = packet.port - res.count = inter.count - res.inter = inter.pin - delete res.status - this.emit('interrupt',res) + if (packet.pins) { // avoid bad interrupt (i.e. no pin caused interrupt) + res.state = (await this.pin.status(packet)).status.pins[0][1] + res.port = packet.port + res.count = inter.count + res.inter = inter.pin + delete res.status + this.emit('interrupt',res) + } + await this._reset(packet.port) + this.ready=true return res } }