added port read and write methods to mcp class

master
David Kebler 2017-05-24 21:15:54 -07:00
parent 832a507204
commit 0fb62e2db1
1 changed files with 222 additions and 250 deletions

View File

@ -2,45 +2,30 @@
const Device = require('uci-dev').Device, const Device = require('uci-dev').Device,
Port = require('uci-gpio').Port, Port = require('uci-gpio').Port,
_u = require('uci-utils'), _u = require('uci-utils'),
pause = _u.pPause pause = _u.pPause,
aseq = _u.aSeq
class MCP23008 extends Device { class MCP23008 extends Device {
constructor(busObj, i2cAddress, opts = {}) { constructor(busObj, i2cAddress, opts = {}) {
super(busObj, i2cAddress, opts) super(busObj, i2cAddress, opts)
// opts could pass in array of custom pin config, or single for all, or anything // opts could include options passed on to ports and pin including custom pin config, pin ids...see gpio.js
// this.registers = registers // load in register database this.chip_config = opts.chip_config // TODO allow opts.chip_config to be a byte instead of a string pointer
this.ports = {} this.ports = {}
opts.portID = 'A' opts.portID = 'A'
opts.pids = opts.pids ? opts.pids : opts.pidsA opts.pids = opts.pids ? opts.pids : opts.pidsA
this.ports.A = new Port(opts) this.ports.A = new Port(opts)
this.chip_config = opts.chip_config // TODO allow opts.chip_config to be a byte instead of a string pointer this.ports.A.state = new _u.Byte(opts.stateA)
this.ports.A.interrupt = opts.interruptA ? opts.interruptA : opts.interrupt this.ports.A.interrupt = opts.interruptA ? opts.interruptA : opts.interrupt
// if (this.ports.A.interrupt) { this.ports.A.interrupt.port = 'A' }
} // end constructor } // end constructor
async init() { async init() {
// console.log('chip configuration', chip_config.cmd, chipSetByte())
// console.log(`begin initialize ${this.id}`) // console.log(`begin initialize ${this.id}`)
await this.writeChipCfg(this.chip_config) await this.writeChipCfg(this.chip_config) // chip settings
// let jobs = [this.writeChipCfg(this.chip_config)] // configure chip
// for (let port in this.ports) {
// if (this.inter(port)) {
// console.log(`initialize interrupt port ${port}`)
// jobs.push(
// this.inter(port).init()
// .then(sbci => {
// this.inter(port).sbci = sbci
// console.log(`sbci ${this.inter(port).sbci}`)
// })
// )
// // sbci = single board computer interrrupt to distinguish it from interrupt on MCP
// }
// }
// jobs.push(this.writePinsCfg())
await this.writePinsCfg() await this.writePinsCfg()
for (let port in this.ports) {
// return _u.pSeries(jobs) console.log(`init port ${port} state`)
await this.writePort(this.state(port), 'force', port)
}
} }
async start() { async start() {
@ -50,7 +35,7 @@ class MCP23008 extends Device {
if (this.inter(port)) { if (this.inter(port)) {
await this.interruptReset(port) await this.interruptReset(port)
await this.inter(port).start() await this.inter(port).start()
// bind handler to the chip to handler can read/write to chip/bank when interrupt is emitted // bind handler to the chip so handler can read/write to chip/bank when interrupt is emitted
let ihandler = this.inter(port).handler.bind(this) let ihandler = this.inter(port).handler.bind(this)
// inside the listener `this` is the interrupt not the chip/bank // inside the listener `this` is the interrupt not the chip/bank
this.inter(port).on('fired', function () { this.inter(port).on('fired', function () {
@ -63,40 +48,8 @@ class MCP23008 extends Device {
async interruptReset(port = 'A') { async interruptReset(port = 'A') {
await this.read(portReg(0x08, port)) await this.read(portReg(0x08, port))
await pause(300) // give enough time for mcp to reset its interupt await pause(100) // give enough time for mcp to reset its interupt
console.log(`interrupt reset on ${this.id} port ${port}`) // console.log(`interrupt reset on ${this.id} port ${port}`)
}
// start() {
// let starts = []
// for (let port in this.ports) {
// if (this.inter(port)) {
// starts.push(
// this.read(portReg(0x08, port))
// .then(_u.pDelay(100)) // give enough time for mcp to reset its interupt
// .then(() => {
// return this.inter(port).start()
// .then(resp => {
// console.log(resp)
// // this.inter(port).on('fired', () => {
// // console.log(`
//interrupt port $ { port } hook me\ n $ { relays }
// `)
// // // hook.bind(this)(port)
// return Promise.resolve()
// })
// return Promise.resolve(`
//interrupt port $ { port } started `)
// })
// .catch(err => console.log("error:", err))
// )
// }
// }
// return Promise.all(starts)
// }
portByInterPin(pin) {
return 'A'
} }
pin(id) { return this.ports.A.pin(id) } // get a reference to a particular pin's object pin(id) { return this.ports.A.pin(id) } // get a reference to a particular pin's object
@ -108,6 +61,10 @@ class MCP23008 extends Device {
return false return false
} }
state(port = 'A') {
return this.ports[port].state.value
}
// get a handle to the ports interrupt // get a handle to the ports interrupt
inter(port = 'A') { inter(port = 'A') {
return this.ports[port].interrupt return this.ports[port].interrupt
@ -119,7 +76,7 @@ class MCP23008 extends Device {
let byte = _u.byteFormat(setting.val, { in: setting.fmt, let byte = _u.byteFormat(setting.val, { in: setting.fmt,
out: 'DEC' out: 'DEC'
}) })
return super.write(chip_config.cmd, byte) return this.write(chip_config.cmd, byte)
.then(() => Promise.resolve(`mcp chip config: reg $ { chip_config.cmd } byte $ { byte } written `)) .then(() => Promise.resolve(`mcp chip config: reg $ { chip_config.cmd } byte $ { byte } written `))
} }
@ -139,7 +96,7 @@ class MCP23008 extends Device {
} }
//console.log(`port $ { port } - setting $ { setting } - reg $ { reg } - byte $ { byte }`) //console.log(`port $ { port } - setting $ { setting } - reg $ { reg } - byte $ { byte }`)
jobs.push( jobs.push(
super.write(portReg(reg, port), byte).then(() => Promise.resolve(` this.write(portReg(reg, port), byte).then(() => Promise.resolve(`
config: wrote $ { byte } to register $ { reg } on port $ { port } config: wrote $ { byte } to register $ { reg } on port $ { port }
`)) `))
) )
@ -148,70 +105,89 @@ class MCP23008 extends Device {
return _u.pSeries(jobs) return _u.pSeries(jobs)
} // end writePinsCfg } // end writePinsCfg
// reads all pins in all ports // read(format = 'PLC') {
readPins(cmd = 'gpio', fmt) { // return u_.byteFormat(this.cur, { in: this.format, out: format })
let jobs = [] // }
let reg = registers.pin_cmd[cmd]
for (let port in this.ports) { async readPort(port, cmd = "gpio") {
jobs.push(() => super.read(portReg(reg, port))) if ('AB'.indexOf(port) === -1) {
cmd = port ? port : "gpio"
port = 'A'
} }
return _u.pSeries(jobs) let result = await this.read(portReg(registers.pin_cmd[cmd], port))
this.ports[port].state.value = result
return result
} }
pinRead(id, opts) { async writePort(byte, op, port = 'A') {
let mcpdev = this; // byte MUST be a decimal
return new Promise(function (resolve, reject) { console.log(`current \n ${this.ports[port].state.toFmt('PLC')}`)
let cmd = opts.cmd ? opts.cmd : 'gpio' console.log(`byte passed ${op} \n ${_u.byteFormat(byte,{in: 'DEC', out:'PLC'})}`)
let fmt = opts.fmt ? opts.fmt : { in: 'PLC', out: 'PLC' } if (op !== 'force') {
let reg = registers.pin_cmd[cmd] byte = this.ports[port].state.bwOp(byte, op)
let gpio = mcpdev.pin(id)
if (!gpio) {
reject('no pin found for given id')
} }
console.log('id of fired pin', id) console.log("byte to write decimal \n", byte)
console.log('port of fired pin', mcpdev.portByPin(id)) console.log(`byte to write \n ${_u.byteFormat(byte, { in: 'DEC', out: 'PLC' })}`)
return mcpdev.read(portReg(reg, mcpdev.portByPin(id))).then(resp => {
resp = _u.byteFormat(resp, { in: 'DEC',
out: 'ARY'
})
let addr = gpio.adr.toFmt('ARY')
// console.log(addr)
// console.log(resp)
resolve(_u.sum(_u.and(addr, resp))) // resolve 1 or 0
}).catch(err => reject(err)) // end Promise
}) // end promise
} // end pinRead await this.write(portReg(registers.pin_cmd.gpio, port), byte)
//update the saved state
this.ports[port].state.value = byte
console.log("\n\n")
}
pinWrite(id, opts) { async on(pins, port, format) {
let mcpdev = this; if ('AB'.indexOf(port) === -1) {
return new Promise(function (resolve, reject) { format = port
let cmd = opts.cmd ? opts.cmd : 'gpio' port = 'A'
let reg = registers.pin_cmd[cmd]
let gpio = mcpdev.pin(id, opts.port)
if (!gpio) {
reject('no pin found for given id')
} }
if (gpio.port === 'B') { if (format) { pins = _u.byteFormat(pins, { in: format, out: 'DEC' }) }
reg = reg + 16 await this.writePort(pins, 'on', port)
}
async allOn(port = 'A') {
let pins = 255
await this.writePort(pins, 'force', port)
}
async off(pins, port, format) {
if ('AB'.indexOf(port) === -1) {
format = port
port = 'A'
}
if (format) { pins = _u.byteFormat(pins, { in: format, out: 'DEC' }) }
await this.writePort(pins, 'off', port)
}
async allOff(port = 'A') {
let pins = 0
await this.writePort(pins, 'force', port)
}
async toggle(pins, port, format) {
if ('AB'.indexOf(port) === -1) {
format = port
port = 'A'
}
if (format) { pins = _u.byteFormat(pins, { in: format, out: 'DEC' }) }
await this.writePort(pins, 'toggle', port)
}
async allToggle(port = 'A') {
let pins = 255
await this.writePort('toggle', port)
}
async force(pins, port, format) {
if ('AB'.indexOf(port) === -1) {
format = port
port = 'A'
}
if (format) { pins = _u.byteFormat(pins, { in: format, out: 'DEC' }) }
await this.writePort(pins, 'force', port)
} }
// call device class read
// console.log('port - reg', gpio.port, reg)
return mcpdev.read(reg).then(resp => {
resp = _u.byteFormat(resp, { in: 'DEC',
out: 'ARY'
})
let addr = gpio.pin.address.toFmt('ARY')
// // console.log(addr)
// console.log(resp)
resolve(_u.sum(_u.and(addr, resp))) // resolve 1 or 0
})
})
// .then(state => console.log(`pin state $ { state }`))
.catch(err => console.log(err)) // end Promise
} // end pinRead
} // end 23008 } // end 23008
module.exports.MCP23008 = MCP23008 module.exports.MCP23008 = MCP23008
class MCP23017 extends MCP23008 { class MCP23017 extends MCP23008 {
@ -221,8 +197,8 @@ class MCP23017 extends MCP23008 {
opts.portID = 'B' opts.portID = 'B'
opts.pids = opts.pidsB opts.pids = opts.pidsB
this.ports.B = new Port(opts) this.ports.B = new Port(opts)
this.ports.B.state = new _u.Byte(opts.stateB)
this.ports.B.interrupt = opts.interruptB ? opts.interruptB : opts.interrupt this.ports.B.interrupt = opts.interruptB ? opts.interruptB : opts.interrupt
// if (this.ports.B.interrupt) { this.ports.B.interrupt.hook = 'B' }
} }
pin(id, port) { pin(id, port) {
@ -239,12 +215,6 @@ class MCP23017 extends MCP23008 {
return this.ports[port].pid(address) return this.ports[port].pid(address)
} }
portByInterPin(pin) {
if (this.ports.A.interrupt.pin_number === pin) { return 'A' }
if (this.ports.B.interrupt.pin_number === pin) { return 'B' }
return false
}
portByPin(id) { portByPin(id) {
console.log('pin id in portbypin', id) console.log('pin id in portbypin', id)
if (this.ports.A.pin(id)) { return 'A' } if (this.ports.A.pin(id)) { return 'A' }
@ -258,7 +228,9 @@ module.exports.MCP23017 = MCP23017
// ============================== // ==============================
function portReg(reg, port) { function portReg(reg, port) {
if (port === 'B') { return reg += 0x10 } else { return reg } // TODO what to return for port B will depend on chip configuration
// if not letter assume index 0,1.
if ((port === 'B') || (port === 1)) { return reg += 0x10 } else { return reg }
} }
/* ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf /* ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf