NetBurner 3.5.8
PDF Version

Arduino Wire-compatible I2C controller/target interface. More...

#include <Wire.h>

Public Member Functions

 TwoWire (void)
 Construct a TwoWire using the platform default I2C module.
 TwoWire (int mod)
 Bind to a specific hardware I2C module, leaving the pins to the caller.
 TwoWire (PinIO scl, PinIO sda)
 Construct a TwoWire using specific SCL/SDA pins.
 TwoWire (int sclpin_num, int sdapin_num)
 Construct a TwoWire using Pins[] array index numbers.
 ~TwoWire ()
 Destructor.
bool isValid () const
 Report whether this object is bound to a hardware I2C module.
void setClock (uint32_t clockbaud)
 Set the I2C clock speed.
void begin (uint8_t slave_addr=0)
 Initialize the I2C interface.
void end ()
 Shut down the I2C interface.
void beginTransmission (uint8_t address)
 Begin a write transaction to a target device.
int endTransmission (bool bStop=true)
 End a write transaction and send data on the bus.
size_t write (const uint8_t *pdata, int len)
 Queue data bytes for transmission.
size_t write (uint8_t v)
 Queue a single byte for transmission.
size_t write (const char *pStr, int len=-1)
 Queue a string for transmission.
int requestFrom (uint8_t address, size_t quantity, bool stop=true)
 Request bytes from a target device.
size_t available ()
 Check how many bytes are available to read.
size_t read (uint8_t *pbuf, size_t maxlen)
 Read available data into a buffer (non-standard extension).
uint8_t read ()
 Read the next byte from the receive buffer.
Target functions
void onReceive (slave_rx_handler *handler)
 Register a callback for target (slave) receive events.
void onRequest (slave_rq_handler *handler)
 Register a callback for target (slave) request events.
void setWireTimeout (int timeout_usec=0, bool reset_on_timeout=false)
 Set the transaction completion timeout.
void clearTimeout ()
 Clear the transaction completion timeout.
bool getWireTimeoutFlag ()
 Check whether a timeout has occurred.
Non-standard extensions
void reset ()
 Reset the I2C peripheral and return the object to an idle state.
bool ping (uint8_t addr)
 Check whether a device is present at the given address.
int writeRegN (uint8_t dAddr, uint32_t reg, const uint8_t *buf, uint32_t blen)
 Write a number of bytes to a device register.
void setNumAddressBytes (uint8_t numAddressBytes=1)
 Specify the register address size for a read or write transaction.
int readRegN (uint8_t dAddr, uint32_t reg, uint8_t *buf, uint32_t blen)
 Read a number of bytes from a device register.
int writeReg8 (uint8_t dAddr, uint32_t reg, uint8_t data)
 Write a single byte to a device register.
int readReg8 (uint8_t dAddr, uint32_t reg, uint8_t &data)
 Read a single byte from a device register.

Detailed Description

Arduino Wire-compatible I2C controller/target interface.

Provides a TwoWire interface for communicating with I2C devices, compatible with the Arduino Wire library API. Internal 256-byte TX and RX buffers are used to stage data for each transaction. All bus operations are thread-safe using semaphore-based locking.

In addition to the standard Wire API, non-standard extensions are provided for register-level I2C access (writeRegN(), readRegN()), bus scanning (ping()), and bus recovery (reset()).

TwoWire always drives a hardware I2C peripheral. It does not fall back to a software bit-banged implementation. For bit-banged I2C on arbitrary GPIO pins, use the separate BBI2C class.

See also
TwoWireObject for a convenience wrapper that binds a TwoWire instance and device address together.
I2C Pin Mapping Reference for the supported SCL/SDA pin combinations and the default pins on each platform.

Constructor & Destructor Documentation

◆ TwoWire() [1/4]

TwoWire::TwoWire ( void )

Construct a TwoWire using the platform default I2C module.

Selects the first entry (index 0) in the platform's valid_i2c[] table. See I2C Pin Mapping Reference for default pins on each platform.

◆ TwoWire() [2/4]

TwoWire::TwoWire ( int mod)

Bind to a specific hardware I2C module, leaving the pins to the caller.

This constructor deliberately does not configure any pins. It binds the peripheral and nothing else, so the SCL and SDA pads keep whatever function they already had. The caller owns the pins.

It is not an incomplete version of the other constructors. A module number on its own does not identify a pin pair, because a module can usually be reached from several. On the SOMRT1061, for example, three different pin pairs reach LPI2C3. Choosing one automatically would mean muxing pads the application never named, which could take over pins already in use for something else.

Use this constructor when the pins are already set up by other means, such as board initialisation code, another TwoWire object on the same module, or your own call to PinIO::function(). If you want the driver to configure the pins, use TwoWire(PinIO, PinIO), TwoWire(int, int) or the parameterless constructor instead.

An object built this way with pins that are not muxed to the peripheral will construct successfully and report isValid() as true, because a module really is bound. It simply will not transact, since the peripheral is not connected to anything. There is no way for the driver to detect that.

Module numbering is platform-dependent:

  • SOMRT1061 (MIMXRT10xx): 1-based (1 = LPI2C1, 2 = LPI2C2, etc.)
  • MODRT1171 (MIMXRT11xx): 1-based (1 = LPI2C1, 2 = LPI2C2, etc.)
  • MODM7AE70 (SAME70): 0-based (0 = TWIHS0, 1 = TWIHS1, etc.)
  • MOD5441X / NANO54415 (MCF5441X): 0-based (0 = I2C0, 1 = I2C1, etc.)
Parameters
modI2C module number (platform-dependent, see above)
See also
TwoWire(PinIO, PinIO), TwoWire(int, int), Per-Platform Pin Tables

◆ TwoWire() [3/4]

TwoWire::TwoWire ( PinIO scl,
PinIO sda )

Construct a TwoWire using specific SCL/SDA pins.

Searches the platform's valid_i2c[] table for a matching pin pair, configures the pins to their I2C alternate function, and initializes the corresponding hardware I2C module.

Warning
If no matching entry is found, no hardware module is bound and the object is left inert: begin() does nothing and every transaction fails. There is no automatic bit-bang fallback. Choose a pin pair from Per-Platform Pin Tables.
Parameters
sclSCL pin
sdaSDA pin
See also
I2C Pin Mapping Reference for supported pin combinations per platform

◆ TwoWire() [4/4]

TwoWire::TwoWire ( int sclpin_num,
int sdapin_num )

Construct a TwoWire using Pins[] array index numbers.

Behaves identically to TwoWire(PinIO, PinIO), but accepts integer indexes into the platform's Pins[] array instead of PinIO objects.

Parameters
sclpin_numSCL pin index in the Pins[] array
sdapin_numSDA pin index in the Pins[] array

◆ ~TwoWire()

TwoWire::~TwoWire ( )

Destructor.

Releases I2C hardware resources. Calls end() if the interface is still active.

Member Function Documentation

◆ available()

size_t TwoWire::available ( )

Check how many bytes are available to read.

Returns the number of unread bytes remaining in the receive buffer after a requestFrom() call.

Return values
Numberof bytes available in the buffer
See also
requestFrom(), read()

◆ begin()

void TwoWire::begin ( uint8_t slave_addr = 0)

Initialize the I2C interface.

Call with no argument (or 0) for controller (master) mode, or with a non-zero 7-bit address for target (slave) mode.

Uses an internal reference counter: multiple begin() calls require a matching number of end() calls before the hardware is released. Call setClock() before the first begin() if a non-default speed is desired.

Parameters
slave_addr7-bit target address (0 = controller/master mode)
See also
end(), setClock()

◆ beginTransmission()

void TwoWire::beginTransmission ( uint8_t address)

Begin a write transaction to a target device.

Sets the target address and clears the transmit buffer. Queue data bytes with write() calls, then call endTransmission() to execute the transaction on the bus. Nothing is sent until endTransmission() is called.


Expand for Example Usage

Write Transaction Example

Example: Write Two Bytes to a Device Register
#include <Wire.h>
void UserMain(void *pd)
{
Wire.beginTransmission(0x48); // Target address
Wire.write(0x01); // Register address
Wire.write(0x80); // Data byte
int result = Wire.endTransmission();
if (result != wire_success)
{
printf("I2C write failed: %d\r\n", result);
}
}
void beginTransmission(uint8_t address)
Begin a write transaction to a target device.
void begin(uint8_t slave_addr=0)
Initialize the I2C interface.
size_t write(const uint8_t *pdata, int len)
Queue data bytes for transmission.
int endTransmission(bool bStop=true)
End a write transaction and send data on the bus.
TwoWire(void)
Construct a TwoWire using the platform default I2C module.
class TwoWire Wire
Pre-declared global TwoWire instance using platform default pins.
Definition I2C/Wire/DocExamples/src/main.cpp:24
const int wire_success
Transaction completed successfully.
Definition Wire.h:255

Parameters
address7-bit I2C address of the target device
See also
endTransmission(), write()

◆ clearTimeout()

void TwoWire::clearTimeout ( )

Clear the transaction completion timeout.

Disables any timeout previously set by setWireTimeout().

See also
setWireTimeout()

◆ end()

void TwoWire::end ( )

Shut down the I2C interface.

Decrements the internal reference counter. The hardware is only released when the counter reaches zero (i.e., every begin() has been matched by an end()).

See also
begin()

◆ endTransmission()

int TwoWire::endTransmission ( bool bStop = true)

End a write transaction and send data on the bus.

Transmits the data queued since beginTransmission(). By default sends a stop condition and releases the bus; pass false to send a repeated start instead (useful for combined write-then-read sequences).

Parameters
bStopIf true (default), sends a stop condition and releases the bus. If false, sends a repeated start for a follow-up transaction.
Return values
wire_success(0) Transaction completed successfully
wire_data_too_big(1) Data exceeds the 256-byte transmit buffer
wire_NACK_on_address(2) Target did not acknowledge its address
wire_NACK_on_data(3) Target did not acknowledge a data byte
wire_other_error(4) Unspecified bus error
wire_timeout(5) Transaction timed out
See also
beginTransmission(), Wire Result Codes

◆ getWireTimeoutFlag()

bool TwoWire::getWireTimeoutFlag ( )

Check whether a timeout has occurred.

Returns true if a transaction has timed out since the last call to clearTimeout() or setWireTimeout().

Return values
trueA timeout has occurred
falseNo timeout has occurred
See also
setWireTimeout(), clearTimeout()

◆ isValid()

bool TwoWire::isValid ( ) const
inline

Report whether this object is bound to a hardware I2C module.

A TwoWire constructed from a pin pair that does not appear in the platform's valid_i2c[] table, or from an out of range module number, has no hardware behind it. Such an object is inert: begin() does nothing, ping() returns false, and the register calls return wire_other_error rather than touching the bus.

Nothing reports that failure at construction time, because a constructor cannot return a status, so check this before use if the pins are not hard-coded.


Expand for Example Usage

Checking a Pin Pair at Startup

TwoWire Wire(sclPin, sdaPin);
if (!Wire.isValid())
{
printf("Those pins are not an I2C pair on this platform\r\n");
return;
}
bool isValid() const
Report whether this object is bound to a hardware I2C module.
Definition Wire.h:449


Return values
trueA hardware module is bound and the object is usable
falseConstruction failed; every call will do nothing or error
See also
Per-Platform Pin Tables for the supported pin combinations

◆ onReceive()

void TwoWire::onReceive ( slave_rx_handler * handler)

Register a callback for target (slave) receive events.

The handler is called from interrupt context when this device (operating in target mode) receives data from a controller. Keep the handler short and avoid blocking calls.

Parameters
handlerPointer to the function to call when bytes are received
See also
onRequest(), begin()

◆ onRequest()

void TwoWire::onRequest ( slave_rq_handler * handler)

Register a callback for target (slave) request events.

The handler is called from interrupt context when a controller requests data from this device. The handler should call write() to queue response bytes. Keep the handler short and avoid blocking calls.

Parameters
handlerPointer to the function to call when bytes are requested
See also
onReceive(), begin()

◆ ping()

bool TwoWire::ping ( uint8_t addr)

Check whether a device is present at the given address.

Sends a start condition and address byte, then checks for an ACK. Useful for scanning the I2C bus to discover connected devices.


Expand for Example Usage

I2C Bus Scan Example

Example: Scan the I2C Bus
printf("Scanning I2C bus...\r\n");
for (uint8_t addr = 1; addr < 127; addr++)
{
if (Wire.ping(addr))
{
printf(" Device found at 0x%02X\r\n", addr);
}
}
bool ping(uint8_t addr)
Check whether a device is present at the given address.
Waiting Out an EEPROM Write Cycle

Example: Acknowledge Polling
After a write, an EEPROM stops answering its address until its internal write cycle completes. Polling ping() until it succeeds waits exactly as long as the device needs, rather than relying on a fixed worst case delay.
int rc = Wire.writeRegN(eepromAddr, memAddress, data, len);
if (rc != wire_success) { printf("write failed, rc %d\r\n", rc); }
while (!Wire.ping(eepromAddr)) { } // wait for the write cycle to finish
rc = Wire.readRegN(eepromAddr, memAddress, buf, len);
int writeRegN(uint8_t dAddr, uint32_t reg, const uint8_t *buf, uint32_t blen)
Write a number of bytes to a device register.
int readRegN(uint8_t dAddr, uint32_t reg, uint8_t *buf, uint32_t blen)
Read a number of bytes from a device register.

A device that never answers leaves that loop spinning, so give it a bound if that would be a problem:

int tries = 0;
while (!Wire.ping(eepromAddr) && (++tries < 100)) { }
if (tries >= 100) { printf("device did not become ready\r\n"); }


Note
ping() waits for a transaction already in progress to finish before probing, so it may be called immediately after a read or write.
Warning
On the MODM7AE70 and SBE70LC (SAME70), a scan built on ping() can miss devices that are present. Occasional false negatives have been observed on those platforms: an address answers, then fails on the very next probe of the same address, and a re-run of the identical code reports every device correctly. The SAME70 peripheral is not considered suitable for address discovery. For a reliable scan on those platforms, use a BBI2C object on the same pins, as demonstrated by bbScanI2CBus() in the PlatformSpecific/SAME70/I2C/AddressScan example.

A false negative from ping() does not mean the device is unusable. Reads and writes to a device you already know the address of are not affected, so this matters for discovery rather than for normal traffic.

Note
A false result never proves a device is absent, on any platform. An address can also fail to answer because the device is busy, held in reset, or still completing an internal operation such as an EEPROM write cycle.
Parameters
addr7-bit I2C address to probe
Return values
trueDevice acknowledged the address
falseNo acknowledgment (device not present, not responding, or, on SAME70, possibly a false negative; see the warning above)

◆ read() [1/2]

uint8_t TwoWire::read ( )
inline

Read the next byte from the receive buffer.

Return values
Thenext byte of data, or 0 if no data is available

◆ read() [2/2]

size_t TwoWire::read ( uint8_t * pbuf,
size_t maxlen )

Read available data into a buffer (non-standard extension).

Copies up to maxlen bytes from the receive buffer into pbuf. This is a non-standard extension not found in the Arduino Wire library.

Parameters
pbufPointer to a buffer to read bytes into
maxlenMaximum number of bytes to read
Return values
Numberof bytes copied, or 0 if no data is available

◆ readReg8()

int TwoWire::readReg8 ( uint8_t dAddr,
uint32_t reg,
uint8_t & data )
inline

Read a single byte from a device register.

Convenience wrapper around readRegN() for single-byte reads.

Parameters
dAddr7-bit I2C device address
regRegister address to read
dataReference to variable in which to store the register data
Returns
Wire Result Codes
See also
readRegN(), writeReg8()

◆ readRegN()

int TwoWire::readRegN ( uint8_t dAddr,
uint32_t reg,
uint8_t * buf,
uint32_t blen )

Read a number of bytes from a device register.

Performs a combined I2C write-read transaction: start → address+W → register byte → repeated-start → address+R → data bytes → stop.

There is no length limit. Reads longer than the internal 256-byte buffer are split automatically into several register reads, each continuing from the register the previous one finished at. The target must therefore auto-increment its register pointer across the whole transfer for a split read to give the same result as one long one, which is the normal behaviour for memories such as EEPROMs.

Parameters
dAddr7-bit I2C device address
regRegister address to read
*bufPointer to buffer to store received data
blenNumber of bytes to read
Returns
Wire Result Codes
See also
writeRegN(), readReg8()

◆ requestFrom()

int TwoWire::requestFrom ( uint8_t address,
size_t quantity,
bool stop = true )

Request bytes from a target device.

Sends a read request to the target device and stores the response in the internal receive buffer. Use available() and read() to retrieve the received data.

If bytes have been queued with write() since beginTransmission(), they are sent first and the read is issued with a repeated start. This is how a register read is built: write the register address, then request the data. In that case the transaction stays with the beginTransmission() target and address is not consulted, since the queued bytes belong to that device.

With nothing queued, this is a plain read and address selects the device directly, so requestFrom() may be called on its own.

Warning
Plain reads through requestFrom() are not implemented on the MODM7AE70 (SAME70), where it returns 0 unless a register address has been queued with write() first. On that platform, either precede the call with beginTransmission() and at least one write(), or do the plain read with setNumAddressBytes(0) followed by readRegN(), which is supported there.

Expand for Example Usage

Read Transaction Examples

Example: Read 2 Bytes from a Device
Wire.requestFrom(0x48, 2); // Request 2 bytes from address 0x48
while (Wire.available())
{
uint8_t b = Wire.read();
printf("Received: 0x%02X\r\n", b);
}
int requestFrom(uint8_t address, size_t quantity, bool stop=true)
Request bytes from a target device.
size_t available()
Check how many bytes are available to read.
size_t read(uint8_t *pbuf, size_t maxlen)
Read available data into a buffer (non-standard extension).
Example: Read from a 16-bit Register Address
uint8_t buf[4];
Wire.write((uint8_t)(0x1234 >> 8)); // Register address, MSB first
Wire.write((uint8_t)(0x1234 & 0xFF));
if (Wire.requestFrom(0x50, 4) == 4) // Repeated start, then read
{
Wire.read(buf, 4);
}

Parameters
address7-bit I2C address of the target device. Used when nothing has been queued with write(); otherwise the pending bytes keep the transaction on the beginTransmission() target.
quantityNumber of bytes to request
stopIf true (default), sends a stop condition after the read. If false, sends a repeated start, keeping the bus for a follow-up transaction.
Return values
Numberof bytes actually read and placed in the receive buffer
See also
beginTransmission(), available(), read()

◆ reset()

void TwoWire::reset ( )

Reset the I2C peripheral and return the object to an idle state.

Use this after a timeout or an incomplete transaction, when the bus is unresponsive. The peripheral is reset, reconfigured and re-enabled, and the object's own transaction state is cleared, so a partly finished transfer cannot leak into the next one. The bus speed, register address width and any target address set by begin() are preserved.

Does nothing if the object is not bound to a hardware module, see isValid().


Expand for Example Usage

Recovering After a Failed Transaction

Example: Retry once through a bus reset
uint8_t val;
if (Wire.readRegN(0x48, 0x00, &val, 1) != wire_success)
{
// The device did not answer. It may be holding the bus, so free it
// and try once more before giving up.
if (Wire.readRegN(0x48, 0x00, &val, 1) != wire_success)
{
printf("Device at 0x48 is not responding\r\n");
}
}
void reset()
Reset the I2C peripheral and return the object to an idle state.

See also
setWireTimeout(), isValid()

◆ setClock()

void TwoWire::setClock ( uint32_t clockbaud)
inline

Set the I2C clock speed.

Must be called before begin() to take effect. Common values:

  • 100000: Standard mode (100 kHz)
  • 400000: Fast mode (400 kHz)

The maximum supported speed is platform-dependent. The default is 100 kHz.

Parameters
clockbaudClock speed in Hz

◆ setNumAddressBytes()

void TwoWire::setNumAddressBytes ( uint8_t numAddressBytes = 1)
inline

Specify the register address size for a read or write transaction.

A number of bytes, from 0 to 3, can be sent to specify an address up to 24-bit (3 bytes): 0 = none, 1 = 8-bits, 2 = 16-bits, 3 = 24-bits. Address bytes are sent most significant first.

The width applies to readRegN(), writeRegN() and the 8-bit convenience wrappers, and stays in effect until changed. If every device on the bus uses the same width, call this once after begin(). With a mix of devices, call it before each transaction.


Expand for Example Usage

Mixed Register Widths on One Bus

uint8_t buf[4];
Wire.setNumAddressBytes(2); // 16-bit register address
Wire.readRegN(0x50, 0x1234, buf, 4); // EEPROM
Wire.setNumAddressBytes(1); // back to 8-bit, the default
Wire.readRegN(0x68, 0x75, buf, 1); // sensor
void setNumAddressBytes(uint8_t numAddressBytes=1)
Specify the register address size for a read or write transaction.
Definition Wire.h:1011


Parameters
numAddressBytesThe number of address bytes to send: 0 - 3. The default value is 1 byte.
Note
Widths of 0 to 3 are supported on every platform. On the MODM7AE70 (SAME70) the width is driven from the TWIHS peripheral's native internal address size field rather than by queuing bytes.
See also
readRegN(), writeRegN()

◆ setWireTimeout()

void TwoWire::setWireTimeout ( int timeout_usec = 0,
bool reset_on_timeout = false )

Set the transaction completion timeout.

Configures a timeout for I2C bus transactions. If a transaction does not complete within the specified time, it is aborted and endTransmission() / requestFrom() returns wire_timeout.

Parameters
timeout_usecTimeout in microseconds (0 = disable timeout)
reset_on_timeoutIf true, automatically calls reset() to recover the bus when a timeout occurs
See also
clearTimeout(), getWireTimeoutFlag(), reset()

◆ write() [1/3]

size_t TwoWire::write ( const char * pStr,
int len = -1 )
inline

Queue a string for transmission.

Copies string data into the transmit buffer. If len is -1, the string length is determined automatically via strlen(). Must be called between beginTransmission() and endTransmission().

Parameters
pStrC-style string to send
lenNumber of bytes to send, or -1 to auto-detect length
Return values
Numberof bytes written to the buffer

◆ write() [2/3]

size_t TwoWire::write ( const uint8_t * pdata,
int len )

Queue data bytes for transmission.

Copies data into the internal 256-byte transmit buffer. Must be called between beginTransmission() and endTransmission(). The total data queued per transaction must not exceed 256 bytes.

Parameters
pdataPointer to data to send
lenNumber of bytes to queue
Return values
Numberof bytes written to the buffer
See also
beginTransmission(), endTransmission()

◆ write() [3/3]

size_t TwoWire::write ( uint8_t v)
inline

Queue a single byte for transmission.

Convenience overload that queues one byte. Must be called between beginTransmission() and endTransmission().

Integer literals select this overload, so Wire.write(0x80) queues one byte. The lone exception is a literal 0, which is also a null pointer constant and therefore ambiguous with write(const char *, int); write a zero byte as Wire.write((uint8_t)0).

Parameters
vByte value to queue
Return values
Numberof bytes written (1 on success)

◆ writeReg8()

int TwoWire::writeReg8 ( uint8_t dAddr,
uint32_t reg,
uint8_t data )
inline

Write a single byte to a device register.

Convenience wrapper around writeRegN() for single-byte writes.

Parameters
dAddr7-bit I2C device address
regRegister address to write
dataData byte to write
Returns
Wire Result Codes
See also
writeRegN(), readReg8()

◆ writeRegN()

int TwoWire::writeRegN ( uint8_t dAddr,
uint32_t reg,
const uint8_t * buf,
uint32_t blen )

Write a number of bytes to a device register.

Performs a complete I2C write transaction: start → address+W → register byte → data bytes → stop. This is equivalent to:

Note that the register address is not auto-incremented; whether the target device increments its internal pointer is device-specific.

There is no length limit. Transfers longer than the internal 256-byte buffer are split automatically into several register transactions, each continuing from the register the previous one finished at. The target must therefore auto-increment its register pointer across the whole transfer for a split read or write to give the same result as one long one, which is the normal behaviour for memories such as EEPROMs.


Expand for Example Usage

Register Write / Read Example

Example: Write and Read a Device Register
// Write 2 bytes to register 0x10 of device at 0x68
uint8_t txBuf[2] = {0xAB, 0xCD};
int result = Wire.writeRegN(0x68, 0x10, txBuf, 2);
// Read 2 bytes from register 0x10 of device at 0x68
uint8_t rxBuf[2];
result = Wire.readRegN(0x68, 0x10, rxBuf, 2);
printf("Reg 0x10: 0x%02X 0x%02X\r\n", rxBuf[0], rxBuf[1]);

Parameters
dAddr7-bit I2C device address
regRegister address to write
*bufPointer to buffer containing data to write
blenNumber of bytes to write
Returns
Wire Result Codes
See also
readRegN(), writeReg8()

The documentation for this class was generated from the following file: