23#include <idfxx/intr_alloc>
29#include <frequency/frequency>
31#include <initializer_list>
57#if SOC_HP_I2C_NUM >= 2
60#if SOC_LP_I2C_NUM >= 1
75#if SOC_I2C_SUPPORT_APB
78#if SOC_I2C_SUPPORT_REF_TICK
81#if SOC_I2C_SUPPORT_XTAL
84#if SOC_I2C_SUPPORT_RTC
89#if SOC_LP_I2C_SUPPORTED
94enum class lp_clk_source :
int {
174#if SOC_LP_I2C_SUPPORTED
175 enum lp_clk_source lp_source_clk = lp_clk_source::default_source;
184#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
270 return _mux->try_lock();
285 [[nodiscard]]
enum port port()
const {
return _port; }
288 [[nodiscard]] freq::hertz
frequency()
const {
return _frequency; }
308 template<
typename Rep,
typename Period>
309 [[nodiscard]] std::vector<uint8_t>
scan_devices(
const std::chrono::duration<Rep, Period>&
timeout)
const {
310 return _scan_devices(std::chrono::ceil<std::chrono::milliseconds>(
timeout));
313#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
333 template<
typename Rep,
typename Period>
334 void probe(uint16_t address,
const std::chrono::duration<Rep, Period>&
timeout)
const {
335 unwrap(_probe(address, std::chrono::ceil<std::chrono::milliseconds>(
timeout)));
356 template<
typename Rep,
typename Period>
358 return _probe(address, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
361#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
373 template<
typename Rep,
typename Period>
389 template<
typename Rep,
typename Period>
391 return _try_wait_all_done(std::chrono::ceil<std::chrono::milliseconds>(
timeout));
397 void _delete() noexcept;
399 [[nodiscard]] std::vector<uint8_t> _scan_devices(std::chrono::milliseconds
timeout) const;
400 [[nodiscard]]
result<
void> _probe(uint16_t address, std::chrono::milliseconds
timeout) const;
401 [[nodiscard]]
result<
void> _try_wait_all_done(std::chrono::milliseconds
timeout) const;
403 mutable std::unique_ptr<std::recursive_mutex> _mux;
406 freq::hertz _frequency;
435 freq::hertz scl_speed{0};
436 uint32_t scl_wait_us = 0;
437#if SOC_I2C_SUPPORT_10BIT_ADDR
438 bool addr_10bit =
false;
440 bool disable_ack_check =
false;
443#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
525 assert(_bus !=
nullptr);
533 [[nodiscard]] uint16_t
address()
const {
return _address; }
535#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
552 template<
typename Rep,
typename Period>
572 template<
typename Rep,
typename Period>
574 if (_handle ==
nullptr) {
577 return _bus->try_probe(_address, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
580#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
608 template<std::convertible_to<std::span<const u
int8_t>>... Buffers>
609 requires(
sizeof...(Buffers) > 1)
610 void transmit(Buffers... buffers) {
611 unwrap(try_transmit(buffers...));
625 void transmit(std::span<
const std::span<const uint8_t>> buffers) {
unwrap(try_transmit(buffers)); }
636 template<
typename Rep,
typename Period>
637 void transmit(std::span<const uint8_t> data,
const std::chrono::duration<Rep, Period>&
timeout) {
653 template<
typename Rep,
typename Period>
655 transmit(std::span<
const std::span<const uint8_t>> buffers,
const std::chrono::duration<Rep, Period>&
timeout) {
668 void transmit(
const uint8_t* buf,
size_t size) {
unwrap(try_transmit(buf, size)); }
680 template<
typename Rep,
typename Period>
681 void transmit(
const uint8_t* buf,
size_t size,
const std::chrono::duration<Rep, Period>&
timeout) {
707 template<std::convertible_to<std::span<const u
int8_t>>... Buffers>
708 requires(
sizeof...(Buffers) > 1)
710 std::array<std::span<const uint8_t>,
sizeof...(Buffers)> arr{buffers...};
711 return try_transmit(std::span<
const std::span<const uint8_t>>{arr});
736 template<
typename Rep,
typename Period>
739 return try_transmit(data.data(), data.size(),
timeout);
753 template<
typename Rep,
typename Period>
755 try_transmit(std::span<
const std::span<const uint8_t>> buffers,
const std::chrono::duration<Rep, Period>&
timeout) {
756 return _try_multi_buffer_transmit(buffers, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
780 template<
typename Rep,
typename Period>
783 return _try_transmit(buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
786#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
812 template<
typename Rep,
typename Period>
843 template<
typename Rep,
typename Period>
846 return _try_change_address(new_address, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
849#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
863 unwrap(try_register_event_callbacks(std::move(on_trans_done)));
880#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
918 template<
typename Rep,
typename Period>
946 template<
typename Rep,
typename Period>
949 return _try_execute_operations(ops, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
952#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
963 [[nodiscard]] std::vector<uint8_t>
receive(
size_t size) {
return unwrap(try_receive(size)); }
976 template<
typename Rep,
typename Period>
977 [[nodiscard]] std::vector<uint8_t>
receive(
size_t size,
const std::chrono::duration<Rep, Period>&
timeout) {
1002 template<
typename Rep,
typename Period>
1003 void receive(uint8_t* buf,
size_t size,
const std::chrono::duration<Rep, Period>&
timeout) {
1026 template<
typename Rep,
typename Period>
1027 void receive(std::span<uint8_t> buf,
const std::chrono::duration<Rep, Period>&
timeout) {
1049 template<
typename Rep,
typename Period>
1052 std::vector<uint8_t> buf(size);
1053 return try_receive(buf,
timeout).transform([&]() {
return buf; });
1077 template<
typename Rep,
typename Period>
1080 return _try_receive(buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1100 template<
typename Rep,
typename Period>
1102 return try_receive(buf.data(), buf.size(),
timeout);
1105#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1127 template<
typename Rep,
typename Period>
1155 template<
typename Rep,
typename Period>
1171 return try_write_register(reg, buf.data(), buf.size(),
DEFAULT_TIMEOUT);
1183 template<
typename Rep,
typename Period>
1186 return try_write_register(reg, buf.data(), buf.size(),
timeout);
1212 template<
typename Rep,
typename Period>
1217 const std::chrono::duration<Rep, Period>&
timeout
1219 return _try_write_register(reg, buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1222#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1234 unwrap(try_write_register(high, low, buf));
1248 template<
typename Rep,
typename Period>
1252 std::span<const uint8_t> buf,
1253 const std::chrono::duration<Rep, Period>&
timeout
1270 unwrap(try_write_register(high, low, buf, size));
1285 template<
typename Rep,
typename Period>
1291 const std::chrono::duration<Rep, Period>&
timeout
1320 template<
typename Rep,
typename Period>
1324 std::span<const uint8_t> buf,
1325 const std::chrono::duration<Rep, Period>&
timeout
1327 return try_write_register(high, low, buf.data(), buf.size(),
timeout);
1355 template<
typename Rep,
typename Period>
1361 const std::chrono::duration<Rep, Period>&
timeout
1363 return _try_write_register(high, low, buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1366#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1377 unwrap(try_write_registers(registers, buf));
1390 template<
typename Rep,
typename Period>
1392 std::span<const uint16_t> registers,
1393 std::span<const uint8_t> buf,
1394 const std::chrono::duration<Rep, Period>&
timeout
1409 void write_registers(std::span<const uint16_t> registers,
const uint8_t* buf,
size_t size) {
1410 unwrap(try_write_registers(registers, buf, size));
1424 template<
typename Rep,
typename Period>
1426 std::span<const uint16_t> registers,
1429 const std::chrono::duration<Rep, Period>&
timeout
1446 void write_registers(std::initializer_list<uint16_t> registers, std::span<const uint8_t> buf) {
1447 write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf);
1460 template<
typename Rep,
typename Period>
1462 std::initializer_list<uint16_t> registers,
1463 std::span<const uint8_t> buf,
1464 const std::chrono::duration<Rep, Period>&
timeout
1466 write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf,
timeout);
1479 void write_registers(std::initializer_list<uint16_t> registers,
const uint8_t* buf,
size_t size) {
1480 write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf, size);
1494 template<
typename Rep,
typename Period>
1496 std::initializer_list<uint16_t> registers,
1499 const std::chrono::duration<Rep, Period>&
timeout
1501 write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf, size,
timeout);
1526 template<
typename Rep,
typename Period>
1528 std::span<const uint16_t> registers,
1529 std::span<const uint8_t> buf,
1530 const std::chrono::duration<Rep, Period>&
timeout
1532 return try_write_registers(registers, buf.data(), buf.size(),
timeout);
1559 template<
typename Rep,
typename Period>
1561 std::span<const uint16_t> registers,
1564 const std::chrono::duration<Rep, Period>&
timeout
1566 return _try_write_registers(registers, buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1582 return try_write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf);
1594 template<
typename Rep,
typename Period>
1596 std::initializer_list<uint16_t> registers,
1597 std::span<const uint8_t> buf,
1598 const std::chrono::duration<Rep, Period>&
timeout
1600 return try_write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf,
timeout);
1614 return try_write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf, size);
1627 template<
typename Rep,
typename Period>
1629 std::initializer_list<uint16_t> registers,
1632 const std::chrono::duration<Rep, Period>&
timeout
1634 return try_write_registers(std::span<const uint16_t>{registers.begin(), registers.size()}, buf, size,
timeout);
1637#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1650 return unwrap(try_read_register(reg, size));
1665 template<
typename Rep,
typename Period>
1666 [[nodiscard]] std::vector<uint8_t>
1692 template<
typename Rep,
typename Period>
1720 template<
typename Rep,
typename Period>
1747 template<
typename Rep,
typename Period>
1750 std::vector<uint8_t> buf(size);
1751 return try_read_register(reg, buf,
timeout).transform([&]() {
return buf; });
1774 template<
typename Rep,
typename Period>
1777 return try_read_register(reg, buf.data(), buf.size(),
timeout);
1803 template<
typename Rep,
typename Period>
1806 return _try_read_register(reg, buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1809#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1822 [[nodiscard]] std::vector<uint8_t>
read_register(uint8_t high, uint8_t low,
size_t size) {
1823 return unwrap(try_read_register(high, low, size));
1839 template<
typename Rep,
typename Period>
1840 [[nodiscard]] std::vector<uint8_t>
1857 unwrap(try_read_register(high, low, buf, size));
1872 template<
typename Rep,
typename Period>
1878 const std::chrono::duration<Rep, Period>&
timeout
1907 template<
typename Rep,
typename Period>
1910 std::vector<uint8_t> buf(size);
1911 return try_read_register(high, low, buf,
timeout).transform([&]() {
return buf; });
1937 template<
typename Rep,
typename Period>
1941 std::span<uint8_t> buf,
1942 const std::chrono::duration<Rep, Period>&
timeout
1944 return try_read_register(high, low, buf.data(), buf.size(),
timeout);
1972 template<
typename Rep,
typename Period>
1978 const std::chrono::duration<Rep, Period>&
timeout
1980 return _try_read_register(high, low, buf, size, std::chrono::ceil<std::chrono::milliseconds>(
timeout));
1986 void _delete() noexcept;
1988 [[nodiscard]]
result<
void> _try_transmit(const uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
1989 [[nodiscard]]
result<
void>
1990 _try_multi_buffer_transmit(std::span<const std::span<const uint8_t>> buffers, std::chrono::milliseconds
timeout);
1991 [[nodiscard]]
result<
void> _try_change_address(uint16_t new_address, std::chrono::milliseconds
timeout);
1992 [[nodiscard]]
result<
void>
1993 _try_execute_operations(std::span<const
operation> ops, std::chrono::milliseconds
timeout);
1994 [[nodiscard]]
result<
void> _try_receive(uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
1996 [[nodiscard]]
result<
void>
1997 _try_write_register(uint16_t reg, const uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
1998 [[nodiscard]]
result<
void>
1999 _try_write_register(uint8_t high, uint8_t low, const uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
2000 [[nodiscard]]
result<
void> _try_write_registers(
2001 std::span<const uint16_t> registers,
2004 std::chrono::milliseconds
timeout
2006 [[nodiscard]]
result<
void>
2007 _try_read_register(uint16_t reg, uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
2008 [[nodiscard]]
result<
void>
2009 _try_read_register(uint8_t high, uint8_t low, uint8_t* buf,
size_t size, std::chrono::milliseconds
timeout);
2013 uint16_t _address = 0;
2014 std::unique_ptr<std::move_only_function<
bool() const>> _on_trans_done;
2034#if SOC_HP_I2C_NUM >= 2
2035 case i2c::port::i2c1:
2038#if SOC_LP_I2C_NUM >= 1
2039 case i2c::port::lp_i2c0:
2043 return "unknown(" + std::to_string(
static_cast<int>(p)) +
")";
2049#include "sdkconfig.h"
2050#ifdef CONFIG_IDFXX_STD_FORMAT
2056struct formatter<
idfxx::i2c::port> {
2057 constexpr auto parse(format_parse_context& ctx) {
return ctx.begin(); }
2059 template<
typename FormatContext>
2062 return std::copy(s.begin(), s.end(), ctx.out());
static constexpr gpio nc()
Returns a GPIO representing "not connected".
I2C master bus controller with thread-safe device access.
master_bus(enum port port, gpio sda, gpio scl, freq::hertz frequency)
Creates a new I2C master bus with default settings.
result< void > try_probe(uint16_t address) const
Probes for a device at the specified address.
std::vector< uint8_t > scan_devices() const
Scans for devices on the bus.
enum port port() const
Returns the I2C port.
std::vector< uint8_t > scan_devices(const std::chrono::duration< Rep, Period > &timeout) const
Scans for devices on the bus.
void probe(uint16_t address, const std::chrono::duration< Rep, Period > &timeout) const
Probes for a device at the specified address.
master_bus & operator=(const master_bus &)=delete
static result< master_bus > make(enum port port, gpio sda, gpio scl, freq::hertz frequency)
Creates a new I2C master bus with default settings.
void wait_all_done(const std::chrono::duration< Rep, Period > &timeout) const
Waits for all pending asynchronous operations on the bus to complete.
result< void > try_probe(uint16_t address, const std::chrono::duration< Rep, Period > &timeout) const
Probes for a device at the specified address.
static result< master_bus > make(enum port port, const struct config &config)
Creates a new I2C master bus.
i2c_master_bus_handle_t handle() const
Returns the underlying ESP-IDF bus handle.
freq::hertz frequency() const
Returns the bus clock frequency in Hz.
void unlock() const
Releases exclusive access to the bus.
master_bus(const master_bus &)=delete
master_bus(master_bus &&other) noexcept
bool try_lock() const noexcept
Tries to acquire exclusive access without blocking.
master_bus(enum port port, const struct config &config)
Creates a new I2C master bus.
void probe(uint16_t address) const
Probes for a device at the specified address.
result< void > try_wait_all_done(const std::chrono::duration< Rep, Period > &timeout) const
Waits for all pending asynchronous operations on the bus to complete.
void lock() const
Acquires exclusive access to the bus.
master_bus & operator=(master_bus &&other) noexcept
I2C device at a specific address with register operations.
void transmit(const uint8_t *buf, size_t size)
Transmits data to the device.
result< void > try_write_registers(std::span< const uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
result< void > try_probe() const
Probes the device.
result< void > try_read_register(uint16_t reg, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
void read_register(uint8_t high, uint8_t low, uint8_t *buf, size_t size)
Reads data from a register.
void write_registers(std::span< const uint16_t > registers, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
result< void > try_write_register(uint16_t reg, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
result< std::vector< uint8_t > > try_receive(size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
void write_registers(std::initializer_list< uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
void write_register(uint8_t high, uint8_t low, std::span< const uint8_t > buf)
Writes data to a register.
result< void > try_execute_operations(std::span< const operation > ops)
Executes a custom sequence of I2C operations.
void write_register(uint16_t reg, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
result< void > try_write_registers(std::span< const uint16_t > registers, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
void write_register(uint16_t reg, const uint8_t *buf, size_t size)
Writes data to a register.
result< void > try_write_register(uint8_t high, uint8_t low, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
void write_register(uint8_t high, uint8_t low, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
std::vector< uint8_t > read_register(uint16_t reg, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
master_device(master_bus &bus, uint16_t address)
Creates a new device on the specified bus.
result< std::vector< uint8_t > > try_read_register(uint16_t reg, size_t size)
Reads data from a register.
void register_event_callbacks(std::move_only_function< bool() const > on_trans_done)
Registers a callback for transaction-done events.
void write_registers(std::initializer_list< uint16_t > registers, std::span< const uint8_t > buf)
Writes data to multiple registers.
result< void > try_write_registers(std::initializer_list< uint16_t > registers, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
void write_register(uint16_t reg, std::span< const uint8_t > buf)
Writes data to a register.
result< void > try_read_register(uint8_t high, uint8_t low, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
void read_register(uint16_t reg, std::span< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
result< void > try_write_registers(std::initializer_list< uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
void write_registers(std::span< const uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
result< void > try_write_register(uint8_t high, uint8_t low, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
result< void > try_write_registers(std::span< const uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
result< void > try_read_register(uint16_t reg, std::span< uint8_t > buf)
Reads data from a register.
result< void > try_write_register(uint8_t high, uint8_t low, const uint8_t *buf, size_t size)
Writes data to a register.
void transmit(std::span< const uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
void receive(uint8_t *buf, size_t size)
Receives data from the device.
result< void > try_register_event_callbacks(std::move_only_function< bool() const > on_trans_done)
Registers a callback for transaction-done events.
void probe() const
Probes the device.
result< void > try_read_register(uint8_t high, uint8_t low, uint8_t *buf, size_t size)
Reads data from a register.
void receive(uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
result< void > try_receive(uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
void probe(const std::chrono::duration< Rep, Period > &timeout) const
Probes the device.
result< std::vector< uint8_t > > try_receive(size_t size)
Receives data from the device.
result< void > try_write_register(uint8_t high, uint8_t low, std::span< const uint8_t > buf)
Writes data to a register.
result< std::vector< uint8_t > > try_read_register(uint8_t high, uint8_t low, size_t size)
Reads data from a register.
result< std::vector< uint8_t > > try_read_register(uint8_t high, uint8_t low, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
void execute_operations(std::span< const operation > ops)
Executes a custom sequence of I2C operations.
result< void > try_transmit(std::span< const std::span< const uint8_t > > buffers, const std::chrono::duration< Rep, Period > &timeout)
Transmits data from multiple buffers in a single I2C transaction.
void read_register(uint8_t high, uint8_t low, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
result< void > try_read_register(uint8_t high, uint8_t low, std::span< uint8_t > buf)
Reads data from a register.
master_device(const master_device &)=delete
std::vector< uint8_t > read_register(uint8_t high, uint8_t low, size_t size)
Reads data from a register.
result< void > try_transmit(Buffers... buffers)
Transmits data from multiple buffers in a single I2C transaction.
result< void > try_write_register(uint16_t reg, std::span< const uint8_t > buf)
Writes data to a register.
result< void > try_write_registers(std::initializer_list< uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
result< void > try_write_register(uint16_t reg, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
void transmit(std::span< const uint8_t > data)
Transmits data to the device.
master_device(master_device &&other) noexcept
void write_registers(std::span< const uint16_t > registers, std::span< const uint8_t > buf)
Writes data to multiple registers.
static result< master_device > make(master_bus &bus, uint16_t address, const struct config &config)
Creates a new device on the specified bus.
void write_registers(std::initializer_list< uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
master_device(master_bus &bus, uint16_t address, const struct config &config)
Creates a new device on the specified bus.
void write_register(uint16_t reg, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
result< void > try_transmit(std::span< const std::span< const uint8_t > > buffers)
Transmits data from multiple buffers in a single I2C transaction.
result< std::vector< uint8_t > > try_read_register(uint16_t reg, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
uint16_t address() const
Returns the device address.
result< void > try_read_register(uint8_t high, uint8_t low, std::span< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
void read_register(uint16_t reg, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
result< void > try_transmit(const uint8_t *buf, size_t size)
Transmits data to the device.
void write_register(uint8_t high, uint8_t low, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
void change_address(uint16_t new_address)
Changes the I2C address used for subsequent operations.
result< void > try_receive(std::span< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
result< void > try_receive(uint8_t *buf, size_t size)
Receives data from the device.
i2c_master_dev_handle_t handle() const
Returns the underlying ESP-IDF device handle.
void read_register(uint16_t reg, std::span< uint8_t > buf)
Reads data from a register.
void transmit(std::span< const std::span< const uint8_t > > buffers)
Transmits data from multiple buffers in a single I2C transaction.
void transmit(const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
result< void > try_write_register(uint16_t reg, const uint8_t *buf, size_t size)
Writes data to a register.
result< void > try_receive(std::span< uint8_t > buf)
Receives data from the device.
std::vector< uint8_t > read_register(uint8_t high, uint8_t low, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
result< void > try_read_register(uint16_t reg, uint8_t *buf, size_t size)
Reads data from a register.
result< void > try_transmit(const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
result< void > try_transmit(std::span< const uint8_t > data)
Transmits data to the device.
void write_registers(std::initializer_list< uint16_t > registers, std::span< const uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
std::vector< uint8_t > receive(size_t size)
Receives data from the device.
std::vector< uint8_t > read_register(uint16_t reg, size_t size)
Reads data from a register.
result< void > try_change_address(uint16_t new_address)
Changes the I2C address used for subsequent operations.
result< void > try_execute_operations(std::span< const operation > ops, const std::chrono::duration< Rep, Period > &timeout)
Executes a custom sequence of I2C operations.
result< void > try_write_registers(std::span< const uint16_t > registers, std::span< const uint8_t > buf)
Writes data to multiple registers.
result< void > try_transmit(std::span< const uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
std::vector< uint8_t > receive(size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
result< void > try_write_registers(std::initializer_list< uint16_t > registers, std::span< const uint8_t > buf)
Writes data to multiple registers.
master_device & operator=(const master_device &)=delete
master_device & operator=(master_device &&other) noexcept
void write_register(uint8_t high, uint8_t low, const uint8_t *buf, size_t size)
Writes data to a register.
void transmit(std::span< const std::span< const uint8_t > > buffers, const std::chrono::duration< Rep, Period > &timeout)
Transmits data from multiple buffers in a single I2C transaction.
result< void > try_probe(const std::chrono::duration< Rep, Period > &timeout) const
Probes the device.
void receive(std::span< uint8_t > buf)
Receives data from the device.
void write_registers(std::span< const uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
void read_register(uint16_t reg, uint8_t *buf, size_t size)
Reads data from a register.
result< void > try_change_address(uint16_t new_address, const std::chrono::duration< Rep, Period > &timeout)
Changes the I2C address used for subsequent operations.
master_bus & bus() const
Returns the parent bus.
void change_address(uint16_t new_address, const std::chrono::duration< Rep, Period > &timeout)
Changes the I2C address used for subsequent operations.
void execute_operations(std::span< const operation > ops, const std::chrono::duration< Rep, Period > &timeout)
Executes a custom sequence of I2C operations.
result< void > try_read_register(uint16_t reg, std::span< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
static result< master_device > make(master_bus &bus, uint16_t address)
Creates a new device on the specified bus.
void receive(std::span< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
operation_command
I2C operation command type for custom transaction sequences.
struct i2c_master_bus_t * i2c_master_bus_handle_t
struct i2c_master_dev_t * i2c_master_dev_handle_t
ack_value
ACK value sent after a read operation.
clk_source
I2C master bus clock source.
port
I2C port identifiers.
static constexpr auto DEFAULT_TIMEOUT
Default timeout for I2C operations.
@ start
Send START or repeated-START condition.
@ read
Read data from the bus.
@ stop
Send STOP condition.
@ write
Write data to the bus.
@ ack
Acknowledge — request more data.
@ nack
Not-acknowledge — signal end of read.
@ default_source
Default clock source for the target.
I2C master driver classes.
intr_level
Hardware interrupt priority levels.
constexpr std::unexpected< std::error_code > error(E e) noexcept
Creates an unexpected error from an error code enum.
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
@ invalid_state
Invalid state.
@ timeout
Operation timed out.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
I2C master bus configuration.
freq::hertz frequency
Clock frequency in Hz.
bool allow_pd
Allow powering down the bus during light sleep.
idfxx::gpio scl
GPIO pin for the SCL line.
idfxx::gpio sda
GPIO pin for the SDA line.
size_t trans_queue_depth
Depth of internal transfer queue for asynchronous transactions.
uint8_t glitch_ignore_cnt
Glitch filter count (0-7). Higher values filter more noise.
bool enable_internal_pullup
Enable internal pull-up resistors on SDA and SCL.
I2C device configuration.
Describes a single operation in a custom I2C transaction sequence.
bool ack_check
(write) Whether to check for ACK.
operation_command command
The operation to perform.
ack_value ack_type
(read) ACK value to send after reading.
std::span< const uint8_t > write_data
(write) Data to send.
std::span< uint8_t > read_data
(read) Buffer to receive into.