Skip to content

Set of useful tools to aid in building other things that delight

License

Notifications You must be signed in to change notification settings

johntalton/and-other-delights

Repository files navigation

And Other Delights

A simple set of abstraction and helpers useful when working with I²C

npm Version GitHub package.json version CI CodeQL GitHub Downloads Per Month GitHub last commit

Contents

📖 BusUtil

A set of helper methods that can smooth the process of reading and writing to addressed based register style I²C devices.

BlockDefinition

A subset of the BusUtil1 methods performs opperations a set of address length pairs.

Thus, the Block is defined as an arrays of 2-length arrays.

const block = [[addr, len], ...]

The following methods utilize this definition to perform multi-register read/write operations.

readBlock

Read a Block defined register (of lenghts) set.

Give an imaginary device with three registers of differnt lengths this example will read from the addressed device and return a buffer containing the data from the device with a length equal to the sum of the definitions register lengths.

// get the good stuff
import i2c from '...'
import { I2CAddressedBus } from '@johntalton/and-other-delights'

// setup a make believe device on bus 1 address 66
const busNumber = 1
const busAddress = 0x42
const bus1 = await i2c.openPromisified(busNumber)
const abus1 = await I2CAddressedBus.from(bus1, busAddress)

// defined a register set of 3,5,7 each with different lengths of 2,1 and 3 respectivly
const block = [[3, 2], [5, 1], [7, 3]]
const buffer = await BusUtil.readBlock(abus1, block)

// 2 + 1 + 3 = 6
assert(bufer.length === 6)

writeBlock

Write the given buffer to the device registers defined by the Block.

The buffer is read as a packed set of bytes equal to the sum of the Blocks total registers length.

// get the good stuff
import i2c from 'i2c-bus'
import { I2CAddressedBus } from '@johntalton/and-other-delights'

// setup a make believe device on bus 1 address 66
const busNumber = 1
const busAddress = 0x42
const bus1 = await i2c.openPromisified(busNumber)
const abus1 = await I2CAddressedBus.from(bus1, busAddress)

// defined a register set of 3,5,7 each with different lengths of 2,1 and 3 respectivly
const block = [[3, 2], [5, 1], [7, 3]]
const buffer = await BusUtil.readBlock(abus1, block)

expandBlock

As a Block is an address / lengthed pairing - the need arises to convert it into a single array.

expandBlock will fill the un-addressed gaps with a specified fill byte.

📖 I²C

A set of I²C interfaces that provide basic interaction.

They are a (simplification and extension) wrapper for the i2c-bus @fivdi implementation.

📖 I2CBus

Interface to provide a stable api to build other I²C APIs around.

An example usage would be to wrap an existing I2CBus class. In this case adding console output.

class LogBus extends I2CBus {
    static from(bus) { return new LogBus(bus) }
    constructor(bus) { this.bus = bus }

    // ... other class methods

    readI2cBlock(addr, cmd, length, buffer) {
        console.log('Reading I2C Block', add, cmd, length);
        this.bus.readI2cBlock(add, cmd, length, buffer)
    }
}

const bus // "other bus" setup code
const lb = LogBus.from(bus)

// using SomeDevice with LogBus proxy into the base bus
const device = SomeDevice.from(bus, options)

📖 I2CAddressedBus

An address-cache wrapper for I²C bus interactions. Providing a I2CManagedBus interface to the device and wrapping an I2CBus.

const ab = await I2CAddressedBus.from(i2cbus, busAddress)

readI2cBlock

Reads a blocks of data of length given a command byte (register address).

Such that the following would read 32-bits from register 0x1A (in a register based device)

const result = await ab.readI2cBlock(0x1A, 4)

writeI2cBlock

Write a block of data to a given 'command' (at register address)

The following would write 32-bits for at the given address.

await ab.writeI2cBlock(0x1A, Uint8Array.from([3, 5, 7, 9))

sendByte

A single byte write command that tipicaly will write the command (register) value with no additional data.

This is useful for command that expect a register set followed by a i2cRead call.

i2cRead

Reads a block of data of a given length. While implementations and designs differ, many devices use this method in conjunction with sendBtye as a set-address/read-data pair.

await ab.sendBtye(0x1A)
const data = await ab.i2cRead(4)

i2cWrite

Write the given data. Implementation specific behavior, however, some devices use this in conjunction with writeSpecial.

await ab.sendBtye(0x1A)
const data = await ab.i2cWrite(Uint8Array.from([3, 5, 7, 9]))

📖 I2CMockBus

An I2CBus implementation that emulates a register layout given a definition file.

Useful for simulating full mocks or persistent data. Also when complex read / write actions are not suitable for a scripted approach (see I2CScriptBus).

📖 I2CScriptBus

An I2CBus implementation that uses an ordered script to govern api call interactions.

About

Set of useful tools to aid in building other things that delight

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages