diff --git a/i2c-bus/i2c-bus-tests.ts b/i2c-bus/i2c-bus-tests.ts new file mode 100644 index 0000000000..1e4c6c8bcb --- /dev/null +++ b/i2c-bus/i2c-bus-tests.ts @@ -0,0 +1,153 @@ +// Tests for i2c-bus/index.d.ts +// Project: https://github.com/fivdi/i2c-bus +// Definitions by: Jason Heard + +// Tests taken from documentation samples. + +import { I2cBus, open, openSync } from "i2c-bus"; +import * as asnc from "async"; + + +function toCelsius(rawTemp: number): number { + const halfDegrees = ((rawTemp & 0xff) << 1) + (rawTemp >> 15); + + if ((halfDegrees & 0x100) === 0) { + return halfDegrees / 2; // Temp +ve + } + + return -((~halfDegrees & 0xff) / 2); // Temp -ve +} + + +/** + * Example 1 from the i2c-bus README file. + */ +function example1(): void { + const i2c1 = openSync(1); + + const DS1621_ADDR = 0x48, + CMD_ACCESS_CONFIG = 0xac, + CMD_READ_TEMP = 0xaa, + CMD_START_CONVERT = 0xee; + + // Enter one shot mode (this is a non volatile setting) + i2c1.writeByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG, 0x01); + + // Wait while non volatile memory busy + while (i2c1.readByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG) & 0x10) { + } + + // Start temperature conversion + i2c1.sendByteSync(DS1621_ADDR, CMD_START_CONVERT); + + // Wait for temperature conversion to complete + while ((i2c1.readByteSync(DS1621_ADDR, CMD_ACCESS_CONFIG) & 0x80) === 0) { + } + + // Display temperature + const rawTemp = i2c1.readWordSync(DS1621_ADDR, CMD_READ_TEMP); + console.log("temp: " + toCelsius(rawTemp)); + + i2c1.closeSync(); +} + + +/** + * Example 2 from the i2c-bus README file. + */ +function example2(): void { + let i2c1: I2cBus; + + const DS1621_ADDR = 0x48, + CMD_ACCESS_CONFIG = 0xac, + CMD_READ_TEMP = 0xaa, + CMD_START_CONVERT = 0xee; + + async.series([ + cb => { + i2c1 = open(1, cb); + }, + cb => { + // Enter one shot mode (this is a non volatile setting) + i2c1.writeByte(DS1621_ADDR, CMD_ACCESS_CONFIG, 0x01, cb); + }, + cb => { + // Wait while non volatile memory busy + (function read(): void { + i2c1.readByte(DS1621_ADDR, CMD_ACCESS_CONFIG, (err, config) => { + if (err) return cb(err); + if (config & 0x10) return read(); + cb(undefined); + }); + }()); + }, + cb => { + // Start temperature conversion + i2c1.sendByte(DS1621_ADDR, CMD_START_CONVERT, cb); + }, + cb => { + // Wait for temperature conversion to complete + (function read(): void { + i2c1.readByte(DS1621_ADDR, CMD_ACCESS_CONFIG, (err, config) => { + if (err) return cb(err); + if ((config & 0x80) === 0) return read(); + cb(undefined); + }); + }()); + }, + cb => { + // Display temperature + i2c1.readWord(DS1621_ADDR, CMD_READ_TEMP, (err, rawTemp) => { + if (err) return cb(err); + console.log("temp: " + toCelsius(rawTemp)); + cb(undefined); + }); + }, + cb => { + i2c1.close(cb); + } + ], err => { + if (err) throw err; + }); +} + + +/** + * Example 3 from the i2c-bus README file. + */ +function example3(): void { + let i2c1: I2cBus; + + const DS1621_ADDR = 0x48, + DS1621_CMD_ACCESS_TH = 0xa1; + + const TSL2561_ADDR = 0x39, + TSL2561_CMD = 0x80, + TSL2561_REG_ID = 0x0a; + + i2c1 = open(1, err => { + if (err) throw err; + + function readTempHigh(): void { + i2c1.readWord(DS1621_ADDR, DS1621_CMD_ACCESS_TH, (err, tempHigh) => { + if (err) throw err; + console.log("temp: " + tempHigh); + // read another temperature + readTempHigh(); + }); + } + + readTempHigh(); + + function readId(): void { + i2c1.readByte(TSL2561_ADDR, TSL2561_CMD | TSL2561_REG_ID, (err, id) => { + if (err) throw err; + console.log("id: " + id); + // read another ID + readId(); + }); + } + + readId(); + }); +} diff --git a/i2c-bus/index.d.ts b/i2c-bus/index.d.ts new file mode 100644 index 0000000000..e03432b75d --- /dev/null +++ b/i2c-bus/index.d.ts @@ -0,0 +1,396 @@ +// Type definitions for i2c-bus v1.0.0 +// Project: https://github.com/fivdi/i2c-bus +// Definitions by: Jason Heard +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// + + +type CompletionCallback = (error: any) => any; + +type BufferCallback = (error: any, bytesReadOrWritten: number, buffer: Buffer) => any; + +type ResultCallback = (error: any, result: T) => any; + +export interface I2cBusFuncs { + i2c: boolean; + tenBitAddr: boolean; + protocolMangling: boolean; + smbusPec: boolean; + smbusBlockProcCall: boolean; + smbusQuick: boolean; + smbusReceiveByte: boolean; + smbusSendByte: boolean; + smbusReadByte: boolean; + smbusWriteByte: boolean; + smbusReadWord: boolean; + smbusWriteWord: boolean; + smbusProcCall: boolean; + smbusReadBlock: boolean; + smbusWriteBlock: boolean; + smbusReadI2cBlock: boolean; + smbusWriteI2cBlock: boolean; +} + +export interface I2cBus { + + /** + * Asynchronous close. + * + * @param {CompletionCallback} callback + * Completion callback + */ + close(callback: CompletionCallback): void; + + /** + * Synchronous close. + */ + closeSync(): void; + + /** + * Determine functionality of the bus/adapter asynchronously. + * + * @param {ResultCallback} callback + * Callback that will recieve a frozen I2cFuncs object describing the I2C functionality available. + */ + i2cFuncs(callback: ResultCallback): void; + + /** + * Determine functionality of the bus/adapter synchronously. + * + * @return {I2cBusFuncs} + * A frozen I2cFuncs object describing the I2C functionality available. + */ + i2cFuncsSync(): I2cBusFuncs; + + /** + * Scans the I2C bus asynchronously for devices the same way i2cdetect -y -r would. + * + * @param {ResultCallback} callback + * Callback that will recieve an array of numbers where each number represents the I2C address of a device which was detected. + */ + scan(callback: ResultCallback): void; + + /** + * Scans the I2C bus synchronously for devices the same way i2cdetect -y -r would. + * + * @return {number[]} + * An array of numbers where each number represents the I2C address of a device which was detected. + */ + scanSync(): number[]; + + /** + * Asynchronous plain I2C read. + * + * @param {number} address + * I2C device address. + * @param {number} length + * The number of bytes to read. + * @param {Buffer} buffer + * The buffer that the data will be written to (must be at least {length} bytes long). + * @param {BufferCallback} callback + * Callback that will recieve the number of bytes read and the given buffer. + */ + i2cRead(address: number, length: number, buffer: Buffer, callback: BufferCallback): void; + + /** + * Synchronous plain I2C read. + * + * @param {number} address + * I2C device address. + * @param {number} length + * The number of bytes to read. + * @param {Buffer} buffer + * The buffer that the data will be written to (must be at least {length} bytes long). + * @return {number} + * The number of bytes read. + */ + i2cReadSync(address: number, length: number, buffer: Buffer): number; + + /** + * Asynchronous plain I2C write. + * + * @param {number} address + * I2C device address. + * @param {number} length + * The number of bytes to write. + * @param {Buffer} buffer + * The buffer that the data to write (must contain at least {length} bytes). + * @param {BufferCallback} callback + * Callback that will recieve the number of bytes written and the given buffer. + */ + i2cWrite(address: number, length: number, buffer: Buffer, callback: BufferCallback): void; + + /** + * Synchronous plain I2C write. + * + * @param {number} address + * I2C device address. + * @param {number} length + * The number of bytes to write. + * @param {Buffer} buffer + * The buffer that the data will to write (must contain at least {length} bytes). + * @return {number} + * The number of bytes written. + */ + i2cWriteSync(address: number, length: number, buffer: Buffer): number; + + /** + * Asynchronous SMBus read byte. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {ResultCallback} callback + * Callback that will recieve the byte read. + */ + readByte(address: number, command: number, callback: ResultCallback): void; + + /** + * Synchronous SMBus read byte. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @return {number} + * The byte read. + */ + readByteSync(address: number, command: number): number; + + /** + * Asynchronous SMBus read word. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {ResultCallback} callback + * Callback that will recieve the word read. + */ + readWord(address: number, command: number, callback: ResultCallback): void; + + /** + * Synchronous SMBus read word. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @return {number} + * The word read. + */ + readWordSync(address: number, command: number): number; + + /** + * Asynchronous I2C block read (not defined by the SMBus + * specification). Reads a block of bytes from a device, from a + * designated register that is specified by cmd. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} length + * The number of bytes to read (max 32). + * @param {Buffer} buffer + * The buffer that the data will be written to (must be at least {length} bytes long). + * @param {BufferCallback} callback + * Callback that will recieve the number of bytes read and the given buffer. + */ + readI2cBlock(address: number, command: number, length: number, buffer: Buffer, callback: BufferCallback): void; + + /** + * Synchronous I2C block read (not defined by the SMBus + * specification). Reads a block of bytes from a device, from a + * designated register that is specified by cmd. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} length + * The number of bytes to read (max 32). + * @param {Buffer} buffer + * The buffer that the data will be written to (must be at least {length} bytes long). + * @return {number} + * The number of bytes read. + */ + readI2cBlockSync(address: number, command: number, length: number, buffer: Buffer): number; + + /** + * Asynchronous SMBus receive byte. + * + * @param {number} address + * I2C device address. + * @param {ResultCallback} callback + * Callback that will recieve the byte received. + */ + receiveByte(address: number, callback: ResultCallback): void; + + /** + * Synchronous SMBus receive byte. + * + * @param {number} address + * I2C device address. + * @return {number} + * The byte received. + */ + receiveByteSync(address: number): number; + + /** + * Asynchronous SMBus send byte. + * + * @param {number} address + * I2C device address. + * @param {number} byte + * The data byte to send. + * @param {CompletionCallback} callback + * Completion callback + */ + sendByte(address: number, byte: number, callback: CompletionCallback): void; + + /** + * Synchronous SMBus send byte. + * + * @param {number} address + * I2C device address. + * @param {number} byte + * The data byte to send. + */ + sendByteSync(address: number, byte: number): void; + + /** + * Asynchronous SMBus write byte. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} byte + * The data byte to write. + * @param {CompletionCallback} callback + * Completion callback + */ + writeByte(address: number, command: number, byte: number, callback: CompletionCallback): void; + + /** + * Synchronous SMBus write byte. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} byte + * The data byte to write. + */ + writeByteSync(address: number, command: number, byte: number): void; + + /** + * Asynchronous SMBus write word. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} word + * The data word to write. + * @param {CompletionCallback} callback + * Completion callback + */ + writeWord(address: number, command: number, word: number, callback: CompletionCallback): void; + + /** + * Synchronous SMBus write word. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} word + * The data word to write. + */ + writeWordSync(address: number, command: number, word: number): void; + + /** + * Asynchronous SMBus quick command. Writes a single bit to the device. + * + * @param {number} address + * I2C device address. + * @param {number} bit + * The data bit to write (0 or 1). + * @param {CompletionCallback} callback + * Completion callback + */ + writeQuick(address: number, command: number, bit: number, callback: CompletionCallback): void; + + /** + * Synchronous SMBus quick command. Writes a single bit to the device. + * + * @param {number} address + * I2C device address. + * @param {number} bit + * The data bit to write (0 or 1). + */ + writeQuickSync(address: number, command: number, bit: number): void; + + /** + * Asynchronous I2C block write (not defined by the SMBus + * specification). Writes a block of bytes to a device, to a designated + * register that is specified by {command}. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} length + * The number of bytes to write (max 32). + * @param {Buffer} buffer + * The buffer that the data to write (must contain at least {length} bytes). + * @param {BufferCallback} callback + * Callback that will recieve the number of bytes written and the given buffer. + */ + writeI2cBlock(address: number, command: number, length: number, buffer: Buffer, callback: BufferCallback): void; + + /** + * Synchronous I2C block write (not defined by the SMBus + * specification). Writes a block of bytes to a device, to a designated + * register that is specified by {command}. + * + * @param {number} address + * I2C device address. + * @param {number} command + * The command code. + * @param {number} length + * The number of bytes to write (max 32). + * @param {Buffer} buffer + * The buffer that the data will to write (must contain at least {length} bytes). + * @return {number} + * The number of bytes written. + */ + writeI2cBlockSync(address: number, command: number, length: number, buffer: Buffer): number; + +} + +/** + * Asynchronous open. + * + * @param {number} busNumber + * The number of the I2C bus/adapter to open, 0 for {/dev/i2c-0}, 1 for {/dev/i2c-1}, etc. + * @param {CompletionCallback} callback + * Completion callback. + * @return {I2cBus} + * A new I2cBus object. + */ +export function open(busNumber: number, calback: CompletionCallback): I2cBus; + +/** + * Synchronous open. + * + * @param {number} busNumber + * The number of the I2C bus/adapter to open, 0 for {/dev/i2c-0}, 1 for {/dev/i2c-1}, etc. + * @return {I2cBus} + * A new I2cBus object. + */ +export function openSync(busNumber: number): I2cBus; diff --git a/i2c-bus/tsconfig.json b/i2c-bus/tsconfig.json new file mode 100644 index 0000000000..174a0be030 --- /dev/null +++ b/i2c-bus/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "../async/index.d.ts", + "index.d.ts", + "i2c-bus-tests.ts" + ] +}