822 lines
19 KiB
JavaScript
822 lines
19 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const i2c = require('bindings')('i2c.node');
|
|
|
|
const BUS_FILE_PREFIX = '/dev/i2c-';
|
|
const FIRST_SCAN_ADDR = 0x03;
|
|
const LAST_SCAN_ADDR = 0x77;
|
|
|
|
// Table 4.
|
|
// https://www.nxp.com/docs/en/user-guide/UM10204.pdf
|
|
const knownManufacturers = [
|
|
{ value: 0x000, name: 'NXP Semiconductors' },
|
|
{ value: 0x001, name: 'NXP Semiconductors (reserved)' },
|
|
{ value: 0x002, name: 'NXP Semiconductors (reserved)' },
|
|
{ value: 0x003, name: 'NXP Semiconductors (reserved)' },
|
|
{ value: 0x004, name: 'Ramtron International' },
|
|
{ value: 0x005, name: 'Analog Devices' },
|
|
{ value: 0x006, name: 'STMicroelectronics' },
|
|
{ value: 0x007, name: 'ON Semiconductor' },
|
|
{ value: 0x008, name: 'Sprintek Corporation' },
|
|
{ value: 0x009, name: 'ESPROS Photonics AG' },
|
|
{ value: 0x00a, name: 'Fujitsu Semiconductor' },
|
|
{ value: 0x00b, name: 'Flir' },
|
|
{ value: 0x00c, name: 'O\u2082Micro' },
|
|
{ value: 0x00d, name: 'Atmel' }
|
|
];
|
|
|
|
const open = (busNumber, options, cb) => {
|
|
if (typeof options === 'function') {
|
|
cb = options;
|
|
options = undefined;
|
|
}
|
|
|
|
checkBusNumber(busNumber);
|
|
checkCallback(cb);
|
|
|
|
const bus = new Bus(busNumber, options);
|
|
|
|
setImmediate(cb, null);
|
|
|
|
return bus;
|
|
};
|
|
|
|
const openSync = (busNumber, options) => {
|
|
checkBusNumber(busNumber);
|
|
|
|
return new Bus(busNumber, options);
|
|
};
|
|
|
|
const openPromisified = (busNumber, options) => new Promise(
|
|
(resolve, reject) => {
|
|
const bus = open(busNumber, options,
|
|
err => err ? reject(err) : resolve(bus.promisifiedBus())
|
|
);
|
|
}
|
|
);
|
|
|
|
const checkBusNumber = busNumber => {
|
|
if (!Number.isInteger(busNumber) || busNumber < 0) {
|
|
throw new Error('Invalid I2C bus number ' + busNumber);
|
|
}
|
|
};
|
|
|
|
const checkAddress = addr => {
|
|
if (!Number.isInteger(addr) || addr < 0 || addr > 0x7f) {
|
|
throw new Error('Invalid I2C address ' + addr);
|
|
}
|
|
};
|
|
|
|
const checkCommand = cmd => {
|
|
if (!Number.isInteger(cmd) || cmd < 0 || cmd > 0xff) {
|
|
throw new Error('Invalid I2C command ' + cmd);
|
|
}
|
|
};
|
|
|
|
const checkCallback = cb => {
|
|
if (typeof cb !== 'function') {
|
|
throw new Error('Invalid callback ' + cb);
|
|
}
|
|
};
|
|
|
|
const checkBuffer = buffer => {
|
|
if (!Buffer.isBuffer(buffer)) {
|
|
throw new Error('Invalid buffer ' + buffer);
|
|
}
|
|
};
|
|
|
|
const checkBufferAndLength = (length, buffer, maxLength) => {
|
|
if (!Number.isInteger(length) ||
|
|
length < 0 ||
|
|
(maxLength !== undefined && length > maxLength)) {
|
|
throw new Error('Invalid buffer length ' + length);
|
|
}
|
|
|
|
checkBuffer(buffer);
|
|
|
|
if (buffer.length < length) {
|
|
throw new Error('Buffer must contain at least ' + length + ' bytes');
|
|
}
|
|
};
|
|
|
|
const checkByte = byte => {
|
|
if (!Number.isInteger(byte) || byte < 0 || byte > 0xff) {
|
|
throw new Error('Invalid byte ' + byte);
|
|
}
|
|
};
|
|
|
|
const checkWord = word => {
|
|
if (!Number.isInteger(word) || word < 0 || word > 0xffff) {
|
|
throw new Error('Invalid word ' + word);
|
|
}
|
|
};
|
|
|
|
const checkBit = bit => {
|
|
if (!Number.isInteger(bit) || bit < 0 || bit > 1) {
|
|
throw new Error('Invalid bit ' + bit);
|
|
}
|
|
};
|
|
|
|
const parseId = id => {
|
|
// Figure 20. UM10204
|
|
const manufacturer = id >> 12 & 0x0fff; // high 12bit
|
|
const product = id & 0x0fff; // low 12bit
|
|
|
|
const known = knownManufacturers.find(man => man.value === manufacturer);
|
|
const name = known !== undefined ? known.name : ('<0x' + manufacturer.toString(16) + '>');
|
|
|
|
return {
|
|
manufacturer: manufacturer,
|
|
product: product,
|
|
name: name
|
|
};
|
|
};
|
|
|
|
const peripheral = (bus, addr, cb) => {
|
|
const device = bus._peripherals[addr];
|
|
|
|
if (device === undefined) {
|
|
fs.open(BUS_FILE_PREFIX + bus._busNumber, 'r+', (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
bus._peripherals[addr] = device;
|
|
|
|
i2c.setAddrAsync(device, addr, bus._forceAccess, err => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
cb(null, device);
|
|
});
|
|
});
|
|
} else {
|
|
setImmediate(cb, null, device);
|
|
}
|
|
};
|
|
|
|
const peripheralSync = (bus, addr) => {
|
|
let peripheral = bus._peripherals[addr];
|
|
|
|
if (peripheral === undefined) {
|
|
peripheral = fs.openSync(BUS_FILE_PREFIX + bus._busNumber, 'r+');
|
|
bus._peripherals[addr] = peripheral;
|
|
i2c.setAddrSync(peripheral, addr, bus._forceAccess);
|
|
}
|
|
|
|
return peripheral;
|
|
};
|
|
|
|
class I2cFuncs {
|
|
constructor(i2cFuncBits) {
|
|
this.i2c = !!(i2cFuncBits & i2c.I2C_FUNC_I2C);
|
|
this.tenBitAddr = !!(i2cFuncBits & i2c.I2C_FUNC_10BIT_ADDR);
|
|
this.protocolMangling = !!(i2cFuncBits & i2c.I2C_FUNC_PROTOCOL_MANGLING);
|
|
this.smbusPec = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_PEC);
|
|
this.smbusBlockProcCall = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_BLOCK_PROC_CALL);
|
|
this.smbusQuick = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_QUICK);
|
|
this.smbusReceiveByte = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_READ_BYTE);
|
|
this.smbusSendByte = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_WRITE_BYTE);
|
|
this.smbusReadByte = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_READ_BYTE_DATA);
|
|
this.smbusWriteByte = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_WRITE_BYTE_DATA);
|
|
this.smbusReadWord = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_READ_WORD_DATA);
|
|
this.smbusWriteWord = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_WRITE_WORD_DATA);
|
|
this.smbusProcCall = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_PROC_CALL);
|
|
this.smbusReadBlock = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_READ_BLOCK_DATA);
|
|
this.smbusWriteBlock = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_WRITE_BLOCK_DATA);
|
|
this.smbusReadI2cBlock = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_READ_I2C_BLOCK);
|
|
this.smbusWriteI2cBlock = !!(i2cFuncBits & i2c.I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
|
|
}
|
|
}
|
|
|
|
class Bus {
|
|
constructor(busNumber, options) {
|
|
options = options || {};
|
|
|
|
this._busNumber = busNumber;
|
|
this._forceAccess = !!options.forceAccess || false;
|
|
this._peripherals = [];
|
|
this._promisifiedBus = new PromisifiedBus(this);
|
|
}
|
|
|
|
promisifiedBus() {
|
|
return this._promisifiedBus;
|
|
}
|
|
|
|
close(cb) {
|
|
checkCallback(cb);
|
|
|
|
const peripherals = this._peripherals.filter(peripheral => {
|
|
return peripheral !== undefined;
|
|
});
|
|
|
|
const closePeripheral = _ => {
|
|
if (peripherals.length === 0) {
|
|
return setImmediate(cb, null);
|
|
}
|
|
|
|
fs.close(peripherals.pop(), err => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
closePeripheral();
|
|
});
|
|
};
|
|
|
|
closePeripheral();
|
|
}
|
|
|
|
closeSync() {
|
|
this._peripherals.forEach(peripheral => {
|
|
if (peripheral !== undefined) {
|
|
fs.closeSync(peripheral);
|
|
}
|
|
});
|
|
|
|
this._peripherals = [];
|
|
}
|
|
|
|
i2cFuncs(cb) {
|
|
checkCallback(cb);
|
|
|
|
if (!this.funcs) {
|
|
peripheral(this, 0, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.i2cFuncsAsync(device, (err, i2cFuncBits) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
this.funcs = Object.freeze(new I2cFuncs(i2cFuncBits));
|
|
cb(null, this.funcs);
|
|
});
|
|
});
|
|
} else {
|
|
setImmediate(cb, null, this.funcs);
|
|
}
|
|
}
|
|
|
|
i2cFuncsSync() {
|
|
if (!this.funcs) {
|
|
this.funcs = Object.freeze(new I2cFuncs(i2c.i2cFuncsSync(peripheralSync(this, 0))));
|
|
}
|
|
|
|
return this.funcs;
|
|
}
|
|
|
|
readByte(addr, cmd, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.readByteAsync(device, cmd, cb);
|
|
});
|
|
}
|
|
|
|
readByteSync(addr, cmd) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
|
|
return i2c.readByteSync(peripheralSync(this, addr), cmd);
|
|
}
|
|
|
|
readWord(addr, cmd, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.readWordAsync(device, cmd, cb);
|
|
});
|
|
}
|
|
|
|
readWordSync(addr, cmd) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
|
|
return i2c.readWordSync(peripheralSync(this, addr), cmd);
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
readBlock(addr, cmd, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBuffer(buffer);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.readBlockAsync(device, cmd, buffer, cb);
|
|
});
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
readBlockSync(addr, cmd, buffer) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBuffer(buffer);
|
|
|
|
return i2c.readBlockSync(peripheralSync(this, addr), cmd, buffer);
|
|
}
|
|
|
|
readI2cBlock(addr, cmd, length, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer, 32);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.readI2cBlockAsync(device, cmd, length, buffer, cb);
|
|
});
|
|
}
|
|
|
|
readI2cBlockSync(addr, cmd, length, buffer) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer, 32);
|
|
|
|
return i2c.readI2cBlockSync(peripheralSync(this, addr), cmd, length, buffer);
|
|
}
|
|
|
|
receiveByte(addr, cb) {
|
|
checkAddress(addr);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.receiveByteAsync(device, cb);
|
|
});
|
|
}
|
|
|
|
receiveByteSync(addr) {
|
|
checkAddress(addr);
|
|
|
|
return i2c.receiveByteSync(peripheralSync(this, addr));
|
|
}
|
|
|
|
sendByte(addr, byte, cb) {
|
|
checkAddress(addr);
|
|
checkByte(byte);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.sendByteAsync(device, byte, cb);
|
|
});
|
|
}
|
|
|
|
sendByteSync(addr, byte) {
|
|
checkAddress(addr);
|
|
checkByte(byte);
|
|
|
|
i2c.sendByteSync(peripheralSync(this, addr), byte);
|
|
|
|
return this;
|
|
}
|
|
|
|
writeByte(addr, cmd, byte, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkByte(byte);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.writeByteAsync(device, cmd, byte, cb);
|
|
});
|
|
}
|
|
|
|
writeByteSync(addr, cmd, byte) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkByte(byte);
|
|
|
|
i2c.writeByteSync(peripheralSync(this, addr), cmd, byte);
|
|
|
|
return this;
|
|
}
|
|
|
|
writeWord(addr, cmd, word, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkWord(word);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.writeWordAsync(device, cmd, word, cb);
|
|
});
|
|
}
|
|
|
|
writeWordSync(addr, cmd, word) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkWord(word);
|
|
|
|
i2c.writeWordSync(peripheralSync(this, addr), cmd, word);
|
|
|
|
return this;
|
|
}
|
|
|
|
writeQuick(addr, bit, cb) {
|
|
checkAddress(addr);
|
|
checkBit(bit);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.writeQuickAsync(device, bit, cb);
|
|
});
|
|
}
|
|
|
|
writeQuickSync(addr, bit) {
|
|
checkAddress(addr);
|
|
checkBit(bit);
|
|
|
|
i2c.writeQuickSync(peripheralSync(this, addr), bit);
|
|
|
|
return this;
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
writeBlock(addr, cmd, length, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.writeBlockAsync(device, cmd, length, buffer, cb);
|
|
});
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
writeBlockSync(addr, cmd, length, buffer) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer);
|
|
|
|
i2c.writeBlockSync(peripheralSync(this, addr), cmd, length, buffer);
|
|
|
|
return this;
|
|
}
|
|
|
|
writeI2cBlock(addr, cmd, length, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer, 32);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.writeI2cBlockAsync(device, cmd, length, buffer, cb);
|
|
});
|
|
}
|
|
|
|
writeI2cBlockSync(addr, cmd, length, buffer) {
|
|
checkAddress(addr);
|
|
checkCommand(cmd);
|
|
checkBufferAndLength(length, buffer, 32);
|
|
|
|
i2c.writeI2cBlockSync(peripheralSync(this, addr), cmd, length, buffer);
|
|
|
|
return this;
|
|
}
|
|
|
|
i2cRead(addr, length, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkBufferAndLength(length, buffer);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
fs.read(device, buffer, 0, length, 0, cb);
|
|
});
|
|
}
|
|
|
|
i2cReadSync(addr, length, buffer) {
|
|
checkAddress(addr);
|
|
checkBufferAndLength(length, buffer);
|
|
|
|
return fs.readSync(peripheralSync(this, addr), buffer, 0, length, 0);
|
|
}
|
|
|
|
i2cWrite(addr, length, buffer, cb) {
|
|
checkAddress(addr);
|
|
checkBufferAndLength(length, buffer);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
fs.write(device, buffer, 0, length, 0, cb);
|
|
});
|
|
}
|
|
|
|
i2cWriteSync(addr, length, buffer) {
|
|
checkAddress(addr);
|
|
checkBufferAndLength(length, buffer);
|
|
|
|
return fs.writeSync(peripheralSync(this, addr), buffer, 0, length, 0);
|
|
}
|
|
|
|
scan(startAddr, endAddr, cb) {
|
|
if (typeof startAddr === 'function') {
|
|
cb = startAddr;
|
|
startAddr = FIRST_SCAN_ADDR;
|
|
endAddr = LAST_SCAN_ADDR;
|
|
} else if (typeof endAddr === 'function') {
|
|
cb = endAddr;
|
|
endAddr = startAddr;
|
|
}
|
|
|
|
checkCallback(cb);
|
|
checkAddress(startAddr);
|
|
checkAddress(endAddr);
|
|
|
|
const scanBus = open(this._busNumber, {forceAccess: this._forceAccess}, err => {
|
|
const addresses = [];
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
const next = addr => {
|
|
if (addr > endAddr) {
|
|
return scanBus.close(err => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
cb(null, addresses);
|
|
});
|
|
}
|
|
|
|
scanBus.receiveByte(addr, err => {
|
|
if (!err) {
|
|
addresses.push(addr);
|
|
}
|
|
|
|
next(addr + 1);
|
|
});
|
|
};
|
|
|
|
next(startAddr);
|
|
});
|
|
}
|
|
|
|
scanSync(startAddr, endAddr) {
|
|
if (typeof startAddr === 'undefined') {
|
|
startAddr = FIRST_SCAN_ADDR;
|
|
endAddr = LAST_SCAN_ADDR;
|
|
} else if (typeof endAddr === 'undefined') {
|
|
endAddr = startAddr;
|
|
}
|
|
|
|
checkAddress(startAddr);
|
|
checkAddress(endAddr);
|
|
|
|
const scanBus = openSync(this._busNumber, {forceAccess: this._forceAccess});
|
|
const addresses = [];
|
|
|
|
for (let addr = startAddr; addr <= endAddr; addr += 1) {
|
|
try {
|
|
scanBus.receiveByteSync(addr);
|
|
addresses.push(addr);
|
|
} catch (ignore) {
|
|
}
|
|
}
|
|
|
|
scanBus.closeSync();
|
|
|
|
return addresses;
|
|
}
|
|
|
|
deviceId(addr, cb) {
|
|
checkAddress(addr);
|
|
checkCallback(cb);
|
|
|
|
peripheral(this, addr, (err, device) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
i2c.deviceIdAsync(device, addr, (err, id) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
|
|
cb(null, parseId(id));
|
|
});
|
|
});
|
|
}
|
|
|
|
deviceIdSync(addr) {
|
|
checkAddress(addr);
|
|
|
|
const mp = i2c.deviceIdSync(peripheralSync(this, addr), addr);
|
|
|
|
return parseId(mp);
|
|
}
|
|
}
|
|
|
|
class PromisifiedBus {
|
|
constructor(bus) {
|
|
this._bus = bus;
|
|
}
|
|
|
|
bus() {
|
|
return this._bus;
|
|
}
|
|
|
|
close() {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.close(err => err ? reject(err) : resolve())
|
|
);
|
|
}
|
|
|
|
i2cFuncs() {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.i2cFuncs((err, funcs) => err ? reject(err) : resolve(funcs))
|
|
);
|
|
}
|
|
|
|
readByte(addr, cmd) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.readByte(addr, cmd,
|
|
(err, byte) => err ? reject(err) : resolve(byte)
|
|
)
|
|
);
|
|
}
|
|
|
|
readWord(addr, cmd) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.readWord(addr, cmd,
|
|
(err, word) => err ? reject(err) : resolve(word)
|
|
)
|
|
);
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
readBlock(addr, cmd, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.readBlock(addr, cmd, buffer,
|
|
(err, bytesRead, buffer) =>
|
|
err ? reject(err) : resolve({bytesRead: bytesRead, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
readI2cBlock(addr, cmd, length, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.readI2cBlock(addr, cmd, length, buffer,
|
|
(err, bytesRead, buffer) =>
|
|
err ? reject(err) : resolve({bytesRead: bytesRead, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
receiveByte(addr) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.receiveByte(addr,
|
|
(err, byte) => err ? reject(err) : resolve(byte)
|
|
)
|
|
);
|
|
}
|
|
|
|
sendByte(addr, byte) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.sendByte(addr, byte,
|
|
err => err ? reject(err) : resolve()
|
|
)
|
|
);
|
|
}
|
|
|
|
writeByte(addr, cmd, byte) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.writeByte(addr, cmd, byte,
|
|
err => err ? reject(err) : resolve()
|
|
)
|
|
);
|
|
}
|
|
|
|
writeWord(addr, cmd, word) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.writeWord(addr, cmd, word,
|
|
err => err ? reject(err) : resolve()
|
|
)
|
|
);
|
|
}
|
|
|
|
writeQuick(addr, bit) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.writeQuick(addr, bit,
|
|
err => err ? reject(err) : resolve()
|
|
)
|
|
);
|
|
}
|
|
|
|
// UNTESTED and undocumented due to lack of supporting hardware
|
|
writeBlock(addr, cmd, length, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.writeBlock(addr, cmd, length, buffer,
|
|
(err, bytesWritten, buffer) =>
|
|
err ? reject(err) : resolve({bytesWritten: bytesWritten, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
writeI2cBlock(addr, cmd, length, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.writeI2cBlock(addr, cmd, length, buffer,
|
|
(err, bytesWritten, buffer) =>
|
|
err ? reject(err) : resolve({bytesWritten: bytesWritten, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
i2cRead(addr, length, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.i2cRead(addr, length, buffer,
|
|
(err, bytesRead, buffer) =>
|
|
err ? reject(err) : resolve({bytesRead: bytesRead, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
i2cWrite(addr, length, buffer) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.i2cWrite(addr, length, buffer,
|
|
(err, bytesWritten, buffer) =>
|
|
err ? reject(err) : resolve({bytesWritten: bytesWritten, buffer: buffer})
|
|
)
|
|
);
|
|
}
|
|
|
|
scan(...args) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.scan(...args,
|
|
(err, devices) => err ? reject(err) : resolve(devices)
|
|
)
|
|
);
|
|
}
|
|
|
|
deviceId(addr) {
|
|
return new Promise((resolve, reject) =>
|
|
this._bus.deviceId(addr, (err, id) => err ? reject(err) : resolve(id))
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
open: open,
|
|
openSync: openSync,
|
|
openPromisified: openPromisified
|
|
};
|
|
|