// import _ from '@uci/utils/src/byte' // import _ from '../../archive/uci-utils/src/byte' import _ from '@uci/utils/src/byte' import { CHIP, PIN } from './config' export const chip = { // 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){ // first make sure chip is in set to BANK=0 if not already let bus = await this.bus.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'} else { if (CHIP[cfg]) setting = CHIP[cfg] else return {error:`no chip settings for ${cfg}`} } let byte = _.byteFormat(setting.val, { in: setting.fmt, out: 'DEC' }) if (byte < 128) byte += 128 // make sure BANK=1 remains on let reg = this.chip17 ? 0x0A : 0x05 bus = await this.bus.write(reg,byte) if (bus.error) return bus bus = await this.bus.read(0x05) if (bus.error) return bus return { cmd:'reply', response:_.byteFormat(bus.response,{in:'DEC',out:'STR'}) } } } // 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} } // first get the current byte (pin) state for that setting export const pin = { cfg: async function(packet){ let cfg = {} let reply = { cmd:'reply', status:{} } packet.cfg = packet.cfg || 'output' if (packet.cfg==='custom') cfg = packet.set else cfg = PIN.cfgset[packet.cfg] for(let name of Object.keys(PIN.setting)) { let op = cfg[name] ? 'on' : 'off' // console.log(name, op) let busreply = await this.pin._state(packet,op,PIN.setting[name]) if (busreply.error) return busreply reply.status[name] = busreply.status } return reply }, // state is equivalent to read 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'} let pins = parsePins(packet.pins) let state = new _.Byte() let bus = await this.bus.read(sreg(reg, packet.port)) if (bus.error) return bus state.value = bus.response reply.status = { port:state.toFmt('ARY'), pins: pins.value.map(pin => { if (state.toFmt('PLC').indexOf(pin) !==-1) return [pin, 'on'] else return [pin,'off'] }) } return reply }, _state: async function(packet,op,reg){ reg = (reg!==undefined)? reg : PIN.cmd.gpio // console.log(op, reg, packet) let reply = { cmd:'reply'} let pins = parsePins(packet.pins) let state = new _.Byte() let bus = await this.bus.read(sreg(reg,packet.port)) if (bus.error) return bus state.value = bus.response bus = await this.bus.write(sreg(reg,packet.port),state.bwOp(pins.value,op,{in:'PLC', out:'DEC'})) if (bus.error) return bus bus = await this.bus.read(sreg(reg,packet.port)) if (bus.error) return bus state.value = bus.response reply.status = state.bwOp(pins.value,'check',{in:'PLC', out:'PLC'}) return reply }, // threse three only for output pins state : { on: async function (packet) { return this.pin._state(packet,'on') }, off: async function (packet) { return this.pin._state(packet,'off') }, toggle: async function (packet) { return this.pin._state(packet,'toggle') } }, // will create packet to determine pin caused interrupt, packet will come from interrupt module interrupt: { reset: async function (port) { console.log('resetting interrupt for port', (port ? 'B' : 'A')) return await this.bus.read(sreg(PIN.cmd.intcap,port)) }, find: async function (inter) { console.log('lookup info on device and port for pin fired',inter.pin, inter.times) let port = null let packet = {pins:'all',reg:'intf', port:port} let res = await this.pin.status(packet) this.pin.interrupt.reset() let pin = _.byteFormat(res.status.port, { in: 'ARY', out: 'PLC' })[0] console.log('pin that caused the interrupt', pin) // found it now tell someone what relay(s) to fire res.pin = pin res.times = inter.times res.inter = inter.pin return res }, report: ()=>{}, // come here after determining which pin to report to requester } } // end pin. const parsePins = function(pins) { if (typeof pins==='number') pins = [pins] if (typeof pins==='string') { if (pins==='all') pins = _.byteFormat(255,{in:'DEC', out:'PLC'}) else pins = pins.split(/[,:\s]+/).map(Number).filter( (x) => !Number.isNaN(x)) } return new _.Byte(pins,'PLC') } const sreg = (reg,port) => { return reg + ((port==='B') ? 0x10 : 0) }