diff --git a/examples/ipc-test.mjs b/examples/ipc-test.mjs index 807d549..1b95155 100644 --- a/examples/ipc-test.mjs +++ b/examples/ipc-test.mjs @@ -25,33 +25,67 @@ const delay = time => new Promise(res=>setTimeout(()=>res(),time)) // } // const pins='2,3,4' - // const pins=3 + const pins=3 // const pins='all' - const pins=[1,3,5,7] - - let packet = {cmd:'chip.cfg'} + // const pins=[1,3,5,7] + let packet = {cmd:'pin.cfg', pins:'all'} + console.dir(packet) + mcpclient.send(packet) + await delay(1000) + packet = {cmd:'pin.cfg', pins:'all', port:'B'} console.dir(packet) mcpclient.send(packet) await delay(1000) packet = {cmd:'pin.state.off', pins:'all' } console.dir(packet) + await delay(1000) mcpclient.send(packet) + packet = {cmd:'pin.state.off', pins:'all', port:'B' } + console.dir(packet) + mcpclient.send(packet) + await delay(1000) + // packet = {cmd:'pin.state.on', pins:pins} + // console.dir(packet) + // mcpclient.send(packet) + packet = {cmd:'pin.state.on', pins:'1,7', port:'B' } + console.dir(packet) + mcpclient.send(packet) + packet = {cmd:'pin.state.on', pins:'3,4'} + console.dir(packet) + mcpclient.send(packet) + + // mcpclient.send(packet) // await delay(1000) + // packet = {cmd:'pin.state.on', pins:pins} + // console.dir(packet) + // mcpclient.send(packet) + // await delay(1000) + // packet = {cmd:'pin.status', reg:'xintf', pins:pins} + // console.dir(packet) + // mcpclient.send(packet) + // await delay(1000) + // packet = {cmd:'pin.status', pins:pins} + // console.dir(packet) + // mcpclient.send(packet) + // await delay(1000) + + + // packet = {cmd:'pin.cfg', pins:pins, cfg:'toggle_switch'} // console.dir(packet) // mcpclient.send(packet) - await delay(1000) - packet = {cmd:'pin.cfg', pins:pins} - console.dir(packet) - mcpclient.send(packet) - await delay(1000) - packet = {cmd:'pin.state.on', pins:pins, } - console.dir(packet) - mcpclient.send(packet) - await delay(1000) - packet = {cmd:'pin.state.toggle', pins:pins, } - console.dir(packet) - mcpclient.send(packet) + // await delay(1000) + // packet = {cmd:'pin.cfg', pins:pins} + // console.dir(packet) + // mcpclient.send(packet) + // await delay(1000) + // packet = {cmd:'pin.state.on', pins:pins, } + // console.dir(packet) + // mcpclient.send(packet) + // await delay(1000) + // packet = {cmd:'pin.state.toggle', pins:pins, } + // console.dir(packet) + // mcpclient.send(packet) // await delay(1000) // packet = {cmd:'pin.state.toggle', pins:pins, } // console.dir(packet) diff --git a/examples/mcp.mjs b/examples/mcp.mjs index f21a1d0..f79fe14 100644 --- a/examples/mcp.mjs +++ b/examples/mcp.mjs @@ -8,7 +8,7 @@ import MCP230XX from '../src/mcp230xx-packet' ; (async () => { - let mcp_chip = new MCP230XX({id:'mcp23008-27', address:0x27, bus:{host:'sbc'} }) + let mcp_chip = new MCP230XX({id:'mcp23008-27', address:0x26, bus:{host:'sbc'} }) await mcp_chip.init() diff --git a/src/commands.mjs b/src/commands.mjs index 085e333..fee49f5 100644 --- a/src/commands.mjs +++ b/src/commands.mjs @@ -4,16 +4,19 @@ import { CHIP, PIN } from './config' export const chip = { ack: async function(packet){ - // process packet based on command and any other props into a bus packet - let bus_packet = { cmd:'scan'} - // console.log(packet.num) - let bus_reply = await this.busSend(bus_packet) - if (bus_reply.error) return bus_reply - let res = { cmd:'reply', _req:packet, _reqBus:bus_packet, ack: false, address:this.address} - if (bus_reply.response.indexOf(parseInt(this.address,16))!=-1) res.ack = true + let bus = await this.busSend({ cmd:'scan'}) + if (bus.error) return bus + let res = { cmd:'reply', _req:packet, _reqBus:{cmd:'scan'}, ack: false, address:this.address, scan:bus.response} + if (bus.response.indexOf(this.address) !== -1) res.ack = true return res }, + // for custom chip configuration set packet.cfg='custom' then packet.setting should be a + // configuration byte with given format ('STR' by defaul). cfg: async function(packet){ + busPacket = busPacket.bind(this) + // first make sure chip is in set to BANK=0 if not already + let bus = await this.busSend(busPacket('write',0x05,0)) + if (bus.error) return bus let setting = {} let cfg = packet.cfg || 'default' if (cfg === 'custom') setting = {val:packet.setting, fmt:packet.fmt || 'STR'} @@ -22,35 +25,15 @@ export const chip = { else return {error:`no chip settings for ${cfg}`} } let byte = _.byteFormat(setting.val, { in: setting.fmt, out: 'DEC' }) - let bus_packet = { cmd:'write', args: {address:this.address, cmd:CHIP.cmd, byte:byte}} - // console.log ('writing mcp chip config', bus_packet) - let bus_reply = await this.busSend(bus_packet) - if (bus_reply.error) return bus_reply - let res = { cmd:'reply', _req:packet, _reqBus:bus_packet , response:bus_reply.response} - return res + if (byte < 128) byte += 128 // make sure BANK=1 remains on + bus = await this.busSend(busPacket('write',0x0A,byte)) + if (bus.error) return bus + bus = await this.busSend(busPacket('read',0x05)) + if (bus.error) return bus + return { cmd:'reply', _req:packet, response:_.byteFormat(bus.response,{in:'DEC',out:'STR'}) } } } - -// async writePinsCfg() { -// debug.L1('writing mcp pins config') -// for (let port in this.ports) { -// for (let setting in registers.pin_config) { -// let reg = registers.pin_config[setting] -// // TODO 0x10 should be based on chip config -// let byte = 0 -// for (let pin of this.ports[port].pins) { -// byte += pin.address * pin.cfg[setting] -// debug.L3(`port: ${ port } pin: ${pin.id} setting: ${ setting } reg: ${ reg } byte: ${ byte }`) -// } -// await this.write(portReg(reg, port), byte) -// } -// } -// debug.L1('done writing mcp pins config') -// } // end writePinsCfg - - - // Individual Pin Configurations // set is for cfg: 'custom' assume a setting is zero unless given // packet = { pin:, port:, cfg: , set:{dir: 0, ivrt: 0, pullup: 0, intr: 0, usedef: 0,defval: 0} } @@ -64,51 +47,30 @@ export const pin = { else cfg = PIN.cfgset[packet.cfg] for(let name of Object.keys(PIN.setting)) { let op = cfg[name] ? 'on' : 'off' - console.log(name, op) + // console.log(name, op) let busreply = await state.bind(this)(packet,op,PIN.setting[name]) if (busreply.error) return busreply - reply.response[name] = reply.status + reply.response[name] = busreply.status } - console.log('==============') return reply }, - - // cfg: async function(packet){ - // let shift = 0 - // let cfg = {} - // let reply = { cmd:'reply', _req:packet, response:{} } - // if (packet.port === 'B') shift= 0x10 // TODO check on shift amount - // packet.cfg = packet.cfg || 'output' - // if (packet.cfg==='custom') cfg = packet.set - // else cfg = PIN.cfgset[packet.cfg] - // let pins = parsePins(packet.pins) - // let state = new _.Byte() - // for(let name of Object.keys(PIN.setting)) { - // let bus_packet = { cmd:'read', args: {address:this.address, cmd:PIN.setting[name]+shift } } - // let bus = await this.busSend(bus_packet) - // if (bus.error) return bus - // state.value = bus.response - // let op = cfg[name] ? 'on' : 'off' - // console.log(name, op) - // console.log(state.toFmt('ARY')) - // console.log(pins.toFmt('ARY')) - // bus_packet = { cmd:'write', args: {address:this.address, cmd:PIN.setting[name]+shift, byte:state.bwOp(pins.value,op,{in:'PLC', out:'DEC'}) } } - // bus = await this.busSend(bus_packet) - // if (bus.error) return bus - // bus_packet = { cmd:'read', args: {address:this.address, cmd:PIN.setting[name]+shift } } - // bus = await this.busSend(bus_packet) - // if (bus.error) return bus - // state.value = bus.response - // console.log(state.toFmt('ARY')) - // reply.response[name] = state.bwOp(pins.value,'check',{in:'PLC', out:'PLC'}) - // } - // console.log('==============') - // return reply - // }, - // state is equivalent to read - status: packet => { + status: async function (packet) { + let reg = packet.reg ? PIN.cmd[packet.reg] : PIN.cmd.gpio + if (!reg) return {error:`unknown register ${packet.reg}`, packet:packet } + let reply = { cmd:'reply', _req:packet} + let pins = parsePins(packet.pins) + let state = new _.Byte() + let bus = await this.busSend(busPacket.bind(this)('read',reg, packet.port)) + if (bus.error) return bus + state.value = bus.response + reply.port = state.toFmt('ARY') + reply.pins = pins.value.map(pin => { + if (state.toFmt('PLC').indexOf(pin) !==-1) return [pin, 'on'] + else return [pin,'off'] + }) + return reply }, // threse three only for output pins state : { @@ -141,28 +103,25 @@ const parsePins = function(pins) { let busPacket = function (cmd,reg,byte,port) { if (typeof byte==='string') port = byte let shift = (port==='B') ? 0x10 : 0 - return { cmd:cmd, args: {address:this.address, cmd:reg+shift, byte:byte } } + let packet = { cmd:cmd, args: {address:this.address, cmd:reg+shift, byte:byte } } + return packet } const state = async function(packet,op,reg){ busPacket = busPacket.bind(this) reg = (reg!==undefined)? reg : PIN.cmd.gpio - console.log(op, reg) + // console.log(op, reg) let reply = { cmd:'reply', _req:packet} let pins = parsePins(packet.pins) let state = new _.Byte() let bus = await this.busSend(busPacket('read',reg, packet.port)) if (bus.error) return bus state.value = bus.response - console.log(state.toFmt('ARY')) - console.log(pins.toFmt('ARY')) - // bus_packet = { cmd:'write', args: {address:this.address, cmd:reg+shift, byte:state.bwOp(pins.value,op,{in:'PLC', out:'DEC'}) } } bus = await this.busSend(busPacket('write',reg,state.bwOp(pins.value,op,{in:'PLC', out:'DEC'}),packet.port)) if (bus.error) return bus bus = await this.busSend(busPacket('read',reg, packet.port)) if (bus.error) return bus state.value = bus.response - console.log(state.toFmt('ARY')) reply.status = state.bwOp(pins.value,'check',{in:'PLC', out:'PLC'}) return reply } diff --git a/src/config.mjs b/src/config.mjs index 133352f..fd98506 100644 --- a/src/config.mjs +++ b/src/config.mjs @@ -3,7 +3,8 @@ export const CHIP = { // The consifuration byte is ['NULL','INTPOL','ODR','HAEN','DISSLW','SEQOP','MIRROR','BANK'] // see page 18 of 23017 datasheet for 8 setting details - cmd: 0x0A, // IOCON.BANK=0 (msb) at powerup so need to use 0x0A, if set to 1 then us + // MUST send '10000000' to 0x0B first to be sure you are in BANK=1 separate bank mode + // IOCON.BANK=0 (msb) at powerup so need to use 0x0A, if set to 1 then us default: { val: '10100010', // Split Banks port A + 0x10 = Port B,(ignored by 23008), Sequential operation disabled, active high=pulldown fmt: 'STR' diff --git a/src/mcp230xx-packet.mjs b/src/mcp230xx-packet.mjs index 14a25c6..75aeb1b 100644 --- a/src/mcp230xx-packet.mjs +++ b/src/mcp230xx-packet.mjs @@ -40,6 +40,10 @@ export default class MCP230XX extends Base { async init(){ await super.init() + let res = await this.chip.ack.bind(this)() // move this to device class + if (!res.ack) throw `no device on this bus at address ${this.address}=0x${this.address.toString(16)}` + res = await this.chip.cfg.bind(this)({}) + if (res.response !== '10100010') throw `could not configure mcp chip at ${this.address}=0x${this.address.toString(16)}` }