idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
master.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
21#include <idfxx/error>
22#include <idfxx/gpio>
23
24#include <chrono>
25#include <frequency/frequency>
26#include <memory>
27#include <mutex>
28#include <string>
29#include <vector>
30
31typedef struct i2c_master_bus_t* i2c_master_bus_handle_t;
32typedef struct i2c_master_dev_t* i2c_master_dev_handle_t;
33
38namespace idfxx::i2c {
39
41static constexpr auto DEFAULT_TIMEOUT = std::chrono::milliseconds(50);
42
47enum class port : int {
48 i2c0 = 0,
49#if SOC_HP_I2C_NUM >= 2
50 i2c1 = 1,
51#endif
52#if SOC_LP_I2C_NUM >= 1
53 lp_i2c0 = 2,
54#endif
55};
56
65public:
76 [[nodiscard]] static result<std::unique_ptr<master_bus>>
77 make(enum port port, gpio sda, gpio scl, freq::hertz frequency);
78
79#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
91 [[nodiscard]] explicit master_bus(enum port port, gpio sda, gpio scl, freq::hertz frequency);
92#endif
93
95
96 master_bus(const master_bus&) = delete;
97 master_bus& operator=(const master_bus&) = delete;
100
102 void lock() const { _mux.lock(); }
103
105 [[nodiscard]] bool try_lock() const noexcept { return _mux.try_lock(); }
106
108 void unlock() const { _mux.unlock(); }
109
111 [[nodiscard]] i2c_master_bus_handle_t handle() const { return _handle; }
112
114 [[nodiscard]] enum port port() const { return _port; }
115
117 [[nodiscard]] freq::hertz frequency() const { return _frequency; }
118
126 [[nodiscard]] std::vector<uint8_t> scan_devices() const { return scan_devices(DEFAULT_TIMEOUT); }
127
137 template<typename Rep, typename Period>
138 [[nodiscard]] std::vector<uint8_t> scan_devices(const std::chrono::duration<Rep, Period>& timeout) const {
139 return _scan_devices(std::chrono::ceil<std::chrono::milliseconds>(timeout));
140 }
141
142#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
151 void probe(uint8_t address) const { probe(address, DEFAULT_TIMEOUT); }
152
162 template<typename Rep, typename Period>
163 void probe(uint8_t address, const std::chrono::duration<Rep, Period>& timeout) const {
164 unwrap(_probe(address, std::chrono::ceil<std::chrono::milliseconds>(timeout)));
165 }
166#endif
167
175 [[nodiscard]] result<void> try_probe(uint8_t address) const { return try_probe(address, DEFAULT_TIMEOUT); }
176
185 template<typename Rep, typename Period>
186 [[nodiscard]] result<void> try_probe(uint8_t address, const std::chrono::duration<Rep, Period>& timeout) const {
187 return _probe(address, std::chrono::ceil<std::chrono::milliseconds>(timeout));
188 }
189
190private:
191 explicit master_bus(i2c_master_bus_handle_t handle, enum port port, freq::hertz frequency);
192
193 [[nodiscard]] std::vector<uint8_t> _scan_devices(std::chrono::milliseconds timeout) const;
194 [[nodiscard]] result<void> _probe(uint8_t address, std::chrono::milliseconds timeout) const;
195
196 mutable std::recursive_mutex _mux;
198 enum port _port;
199 freq::hertz _frequency;
200};
201
210public:
219 [[nodiscard]] static result<std::unique_ptr<master_device>> make(std::shared_ptr<master_bus> bus, uint8_t address);
220
221#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
231 [[nodiscard]] explicit master_device(std::shared_ptr<master_bus> bus, uint8_t address);
232#endif
233
235
236 master_device(const master_device&) = delete;
240
242 [[nodiscard]] const std::shared_ptr<master_bus>& bus() const { return _bus; }
243
245 [[nodiscard]] i2c_master_dev_handle_t handle() const { return _handle; }
246
248 [[nodiscard]] uint8_t address() const { return _address; }
249
250#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
257 void probe() const { probe(DEFAULT_TIMEOUT); }
258
267 template<typename Rep, typename Period>
268 void probe(const std::chrono::duration<Rep, Period>& timeout) const {
269 _bus->probe(_address, std::chrono::ceil<std::chrono::milliseconds>(timeout));
270 }
271#endif
272
278 [[nodiscard]] result<void> try_probe() const { return try_probe(DEFAULT_TIMEOUT); }
279
287 template<typename Rep, typename Period>
288 [[nodiscard]] result<void> try_probe(const std::chrono::duration<Rep, Period>& timeout) const {
289 return _bus->try_probe(_address, std::chrono::ceil<std::chrono::milliseconds>(timeout));
290 }
291
292#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
301 void transmit(const std::vector<uint8_t> data) { unwrap(try_transmit(data)); }
302
312 template<typename Rep, typename Period>
313 void transmit(const std::vector<uint8_t> data, const std::chrono::duration<Rep, Period>& timeout) {
315 }
316
326 void transmit(const uint8_t* buf, size_t size) { unwrap(try_transmit(buf, size)); }
327
338 template<typename Rep, typename Period>
339 void transmit(const uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
340 unwrap(try_transmit(buf, size, timeout));
341 }
342#endif
343
351 [[nodiscard]] result<void> try_transmit(const std::vector<uint8_t> data) {
352 return try_transmit(data, DEFAULT_TIMEOUT);
353 }
354
363 template<typename Rep, typename Period>
364 [[nodiscard]] result<void>
365 try_transmit(const std::vector<uint8_t> data, const std::chrono::duration<Rep, Period>& timeout) {
366 return try_transmit(data.data(), data.size(), timeout);
367 }
368
377 [[nodiscard]] result<void> try_transmit(const uint8_t* buf, size_t size) {
378 return try_transmit(buf, size, DEFAULT_TIMEOUT);
379 }
380
390 template<typename Rep, typename Period>
391 [[nodiscard]] result<void>
392 try_transmit(const uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
393 return _try_transmit(buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
394 }
395
396#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
407 [[nodiscard]] std::vector<uint8_t> receive(size_t size) { return unwrap(try_receive(size)); }
408
420 template<typename Rep, typename Period>
421 [[nodiscard]] std::vector<uint8_t> receive(size_t size, const std::chrono::duration<Rep, Period>& timeout) {
422 return unwrap(try_receive(size, timeout));
423 }
424
434 void receive(uint8_t* buf, size_t size) { unwrap(try_receive(buf, size)); }
435
446 template<typename Rep, typename Period>
447 void receive(uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
448 unwrap(try_receive(buf, size, timeout));
449 }
450
459 void receive(std::vector<uint8_t> buf) { unwrap(try_receive(buf)); }
460
471 template<typename Rep, typename Period>
472 void receive(std::vector<uint8_t> buf, const std::chrono::duration<Rep, Period>& timeout) {
474 }
475#endif
476
484 [[nodiscard]] result<std::vector<uint8_t>> try_receive(size_t size) { return try_receive(size, DEFAULT_TIMEOUT); }
485
494 template<typename Rep, typename Period>
495 [[nodiscard]] result<std::vector<uint8_t>>
496 try_receive(size_t size, const std::chrono::duration<Rep, Period>& timeout) {
497 std::vector<uint8_t> buf(size);
498 return try_receive(buf, timeout).transform([&]() { return buf; });
499 }
500
509 [[nodiscard]] result<void> try_receive(uint8_t* buf, size_t size) {
510 return try_receive(buf, size, DEFAULT_TIMEOUT);
511 }
512
522 template<typename Rep, typename Period>
523 [[nodiscard]] result<void>
524 try_receive(uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
525 return _try_receive(buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
526 }
527
535 [[nodiscard]] result<void> try_receive(std::vector<uint8_t> buf) { return try_receive(buf, DEFAULT_TIMEOUT); }
536
545 template<typename Rep, typename Period>
546 [[nodiscard]] result<void>
547 try_receive(std::vector<uint8_t> buf, const std::chrono::duration<Rep, Period>& timeout) {
548 return try_receive(buf.data(), buf.size(), timeout);
549 }
550
551#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
561 void write_register(uint16_t reg, const std::vector<uint8_t> buf) { unwrap(try_write_register(reg, buf)); }
562
573 template<typename Rep, typename Period>
574 void
575 write_register(uint16_t reg, const std::vector<uint8_t> buf, const std::chrono::duration<Rep, Period>& timeout) {
577 }
578
589 void write_register(uint16_t reg, const uint8_t* buf, size_t size) { unwrap(try_write_register(reg, buf, size)); }
590
602 template<typename Rep, typename Period>
603 void
604 write_register(uint16_t reg, const uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
605 unwrap(try_write_register(reg, buf, size, timeout));
606 }
607#endif
608
617 [[nodiscard]] result<void> try_write_register(uint16_t reg, const std::vector<uint8_t> buf) {
618 return try_write_register(reg, buf.data(), buf.size(), DEFAULT_TIMEOUT);
619 }
620
630 template<typename Rep, typename Period>
632 uint16_t reg,
633 const std::vector<uint8_t> buf,
634 const std::chrono::duration<Rep, Period>& timeout
635 ) {
636 return try_write_register(reg, buf.data(), buf.size(), timeout);
637 }
638
648 [[nodiscard]] result<void> try_write_register(uint16_t reg, const uint8_t* buf, size_t size) {
649 return try_write_register(reg, buf, size, DEFAULT_TIMEOUT);
650 }
651
662 template<typename Rep, typename Period>
664 uint16_t reg,
665 const uint8_t* buf,
666 size_t size,
667 const std::chrono::duration<Rep, Period>& timeout
668 ) {
669 return _try_write_register(reg, buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
670 }
671
672#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
683 void write_register(uint8_t regHigh, uint8_t regLow, const std::vector<uint8_t> buf) {
684 unwrap(try_write_register(regHigh, regLow, buf));
685 }
686
698 template<typename Rep, typename Period>
700 uint8_t regHigh,
701 uint8_t regLow,
702 const std::vector<uint8_t> buf,
703 const std::chrono::duration<Rep, Period>& timeout
704 ) {
705 unwrap(try_write_register(regHigh, regLow, buf, timeout));
706 }
707
719 void write_register(uint8_t regHigh, uint8_t regLow, const uint8_t* buf, size_t size) {
720 unwrap(try_write_register(regHigh, regLow, buf, size));
721 }
722
735 template<typename Rep, typename Period>
737 uint8_t regHigh,
738 uint8_t regLow,
739 const uint8_t* buf,
740 size_t size,
741 const std::chrono::duration<Rep, Period>& timeout
742 ) {
743 unwrap(try_write_register(regHigh, regLow, buf, size, timeout));
744 }
745#endif
746
756 [[nodiscard]] result<void> try_write_register(uint8_t regHigh, uint8_t regLow, const std::vector<uint8_t> buf) {
757 return try_write_register(regHigh, regLow, buf, DEFAULT_TIMEOUT);
758 }
759
770 template<typename Rep, typename Period>
772 uint8_t regHigh,
773 uint8_t regLow,
774 const std::vector<uint8_t> buf,
775 const std::chrono::duration<Rep, Period>& timeout
776 ) {
777 return try_write_register(regHigh, regLow, buf.data(), buf.size(), timeout);
778 }
779
790 [[nodiscard]] result<void> try_write_register(uint8_t regHigh, uint8_t regLow, const uint8_t* buf, size_t size) {
791 return try_write_register(regHigh, regLow, buf, size, DEFAULT_TIMEOUT);
792 }
793
805 template<typename Rep, typename Period>
807 uint8_t regHigh,
808 uint8_t regLow,
809 const uint8_t* buf,
810 size_t size,
811 const std::chrono::duration<Rep, Period>& timeout
812 ) {
813 return _try_write_register(regHigh, regLow, buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
814 }
815
816#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
826 void write_registers(std::vector<uint16_t> registers, const std::vector<uint8_t> buf) {
827 unwrap(try_write_registers(registers, buf));
828 }
829
840 template<typename Rep, typename Period>
842 std::vector<uint16_t> registers,
843 const std::vector<uint8_t> buf,
844 const std::chrono::duration<Rep, Period>& timeout
845 ) {
846 unwrap(try_write_registers(registers, buf, timeout));
847 }
848
859 void write_registers(std::vector<uint16_t> registers, const uint8_t* buf, size_t size) {
860 unwrap(try_write_registers(registers, buf, size));
861 }
862
874 template<typename Rep, typename Period>
876 std::vector<uint16_t> registers,
877 const uint8_t* buf,
878 size_t size,
879 const std::chrono::duration<Rep, Period>& timeout
880 ) {
881 unwrap(try_write_registers(registers, buf, size, timeout));
882 }
883#endif
884
893 [[nodiscard]] result<void> try_write_registers(std::vector<uint16_t> registers, const std::vector<uint8_t> buf) {
894 return try_write_registers(registers, buf, DEFAULT_TIMEOUT);
895 }
896
906 template<typename Rep, typename Period>
908 std::vector<uint16_t> registers,
909 const std::vector<uint8_t> buf,
910 const std::chrono::duration<Rep, Period>& timeout
911 ) {
912 return try_write_registers(registers, buf.data(), buf.size(), timeout);
913 }
914
924 [[nodiscard]] result<void> try_write_registers(std::vector<uint16_t> registers, const uint8_t* buf, size_t size) {
925 return try_write_registers(registers, buf, size, DEFAULT_TIMEOUT);
926 }
927
938 template<typename Rep, typename Period>
940 std::vector<uint16_t> registers,
941 const uint8_t* buf,
942 size_t size,
943 const std::chrono::duration<Rep, Period>& timeout
944 ) {
945 return _try_write_registers(registers, buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
946 }
947
948#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
960 [[nodiscard]] std::vector<uint8_t> read_register(uint16_t reg, size_t size) {
961 return unwrap(try_read_register(reg, size));
962 }
963
976 template<typename Rep, typename Period>
977 [[nodiscard]] std::vector<uint8_t>
978 read_register(uint16_t reg, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
979 return unwrap(try_read_register(reg, size, timeout));
980 }
981
991 void read_register(uint16_t reg, std::vector<uint8_t> buf) { unwrap(try_read_register(reg, buf)); }
992
1003 template<typename Rep, typename Period>
1004 void read_register(uint16_t reg, std::vector<uint8_t> buf, const std::chrono::duration<Rep, Period>& timeout) {
1005 unwrap(try_read_register(reg, buf, timeout));
1006 }
1007
1018 void read_register(uint16_t reg, uint8_t* buf, size_t size) { unwrap(try_read_register(reg, buf, size)); }
1019
1031 template<typename Rep, typename Period>
1032 void read_register(uint16_t reg, uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
1033 unwrap(try_read_register(reg, buf, size, timeout));
1034 }
1035#endif
1036
1045 [[nodiscard]] result<std::vector<uint8_t>> try_read_register(uint16_t reg, size_t size) {
1046 return try_read_register(reg, size, DEFAULT_TIMEOUT);
1047 }
1048
1058 template<typename Rep, typename Period>
1059 [[nodiscard]] result<std::vector<uint8_t>>
1060 try_read_register(uint16_t reg, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
1061 std::vector<uint8_t> buf(size);
1062 return try_read_register(reg, buf, timeout).transform([&]() { return buf; });
1063 }
1064
1073 [[nodiscard]] result<void> try_read_register(uint16_t reg, std::vector<uint8_t>& buf) {
1074 return try_read_register(reg, buf, DEFAULT_TIMEOUT);
1075 }
1076
1085 template<typename Rep, typename Period>
1086 [[nodiscard]] result<void>
1087 try_read_register(uint16_t reg, std::vector<uint8_t>& buf, const std::chrono::duration<Rep, Period>& timeout) {
1088 return try_read_register(reg, buf.data(), buf.size(), timeout);
1089 }
1090
1100 [[nodiscard]] result<void> try_read_register(uint16_t reg, uint8_t* buf, size_t size) {
1101 return try_read_register(reg, buf, size, DEFAULT_TIMEOUT);
1102 }
1103
1114 template<typename Rep, typename Period>
1115 [[nodiscard]] result<void>
1116 try_read_register(uint16_t reg, uint8_t* buf, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
1117 return _try_read_register(reg, buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
1118 }
1119
1120#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
1133 [[nodiscard]] std::vector<uint8_t> read_register(uint8_t regHigh, uint8_t regLow, size_t size) {
1134 return unwrap(try_read_register(regHigh, regLow, size));
1135 }
1136
1150 template<typename Rep, typename Period>
1151 [[nodiscard]] std::vector<uint8_t>
1152 read_register(uint8_t regHigh, uint8_t regLow, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
1153 return unwrap(try_read_register(regHigh, regLow, size, timeout));
1154 }
1155
1167 void read_register(uint8_t regHigh, uint8_t regLow, uint8_t* buf, size_t size) {
1168 unwrap(try_read_register(regHigh, regLow, buf, size));
1169 }
1170
1183 template<typename Rep, typename Period>
1185 uint8_t regHigh,
1186 uint8_t regLow,
1187 uint8_t* buf,
1188 size_t size,
1189 const std::chrono::duration<Rep, Period>& timeout
1190 ) {
1191 unwrap(try_read_register(regHigh, regLow, buf, size, timeout));
1192 }
1193#endif
1194
1204 [[nodiscard]] result<std::vector<uint8_t>> try_read_register(uint8_t regHigh, uint8_t regLow, size_t size) {
1205 return try_read_register(regHigh, regLow, size, DEFAULT_TIMEOUT);
1206 }
1207
1218 template<typename Rep, typename Period>
1219 [[nodiscard]] result<std::vector<uint8_t>>
1220 try_read_register(uint8_t regHigh, uint8_t regLow, size_t size, const std::chrono::duration<Rep, Period>& timeout) {
1221 std::vector<uint8_t> buf(size);
1222 return try_read_register(regHigh, regLow, buf, timeout).transform([&]() { return buf; });
1223 }
1224
1234 [[nodiscard]] result<void> try_read_register(uint8_t regHigh, uint8_t regLow, std::vector<uint8_t> buf) {
1235 return try_read_register(regHigh, regLow, buf, DEFAULT_TIMEOUT);
1236 }
1237
1248 template<typename Rep, typename Period>
1250 uint8_t regHigh,
1251 uint8_t regLow,
1252 std::vector<uint8_t> buf,
1253 const std::chrono::duration<Rep, Period>& timeout
1254 ) {
1255 return try_read_register(regHigh, regLow, buf.data(), buf.size(), timeout);
1256 }
1257
1268 [[nodiscard]] result<void> try_read_register(uint8_t regHigh, uint8_t regLow, uint8_t* buf, size_t size) {
1269 return try_read_register(regHigh, regLow, buf, size, DEFAULT_TIMEOUT);
1270 }
1271
1283 template<typename Rep, typename Period>
1285 uint8_t regHigh,
1286 uint8_t regLow,
1287 uint8_t* buf,
1288 size_t size,
1289 const std::chrono::duration<Rep, Period>& timeout
1290 ) {
1291 return _try_read_register(regHigh, regLow, buf, size, std::chrono::ceil<std::chrono::milliseconds>(timeout));
1292 }
1293
1294private:
1295 explicit master_device(std::shared_ptr<master_bus> bus, i2c_master_dev_handle_t handle, uint8_t address);
1296
1297 [[nodiscard]] result<void> _try_transmit(const uint8_t* buf, size_t size, std::chrono::milliseconds timeout);
1298 [[nodiscard]] result<void> _try_receive(uint8_t* buf, size_t size, std::chrono::milliseconds timeout);
1299
1300 [[nodiscard]] result<void>
1301 _try_write_register(uint16_t reg, const uint8_t* buf, size_t size, std::chrono::milliseconds timeout);
1302 [[nodiscard]] result<void> _try_write_register(
1303 uint8_t regHigh,
1304 uint8_t regLow,
1305 const uint8_t* buf,
1306 size_t size,
1307 std::chrono::milliseconds timeout
1308 );
1309 [[nodiscard]] result<void> _try_write_registers(
1310 std::vector<uint16_t> registers,
1311 const uint8_t* buf,
1312 size_t size,
1313 std::chrono::milliseconds timeout
1314 );
1315 [[nodiscard]] result<void>
1316 _try_read_register(uint16_t reg, uint8_t* buf, size_t size, std::chrono::milliseconds timeout);
1317 [[nodiscard]] result<void>
1318 _try_read_register(uint8_t regHigh, uint8_t regLow, uint8_t* buf, size_t size, std::chrono::milliseconds timeout);
1319
1320 std::shared_ptr<master_bus> _bus;
1322 uint8_t _address;
1323};
1324
// end of idfxx_i2c
1326
1327} // namespace idfxx::i2c
1328
1329namespace idfxx {
1330
1338[[nodiscard]] inline std::string to_string(i2c::port p) {
1339 switch (p) {
1340 case i2c::port::i2c0:
1341 return "I2C0";
1342#if SOC_HP_I2C_NUM >= 2
1343 case i2c::port::i2c1:
1344 return "I2C1";
1345#endif
1346#if SOC_LP_I2C_NUM >= 1
1347 case i2c::port::lp_i2c0:
1348 return "LP_I2C0";
1349#endif
1350 default:
1351 return "unknown(" + std::to_string(static_cast<int>(p)) + ")";
1352 }
1353}
1354
1355} // namespace idfxx
1356
1357#include "sdkconfig.h"
1358#ifdef CONFIG_IDFXX_STD_FORMAT
1360#include <algorithm>
1361#include <format>
1362namespace std {
1363template<>
1364struct formatter<idfxx::i2c::port> {
1365 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
1366
1367 template<typename FormatContext>
1368 auto format(idfxx::i2c::port p, FormatContext& ctx) const {
1369 auto s = idfxx::to_string(p);
1370 return std::copy(s.begin(), s.end(), ctx.out());
1371 }
1372};
1373} // namespace std
1375#endif // CONFIG_IDFXX_STD_FORMAT
A GPIO pin.
Definition gpio.hpp:58
I2C master bus controller with thread-safe device access.
Definition master.hpp:64
master_bus(enum port port, gpio sda, gpio scl, freq::hertz frequency)
Creates a new I2C master bus.
std::vector< uint8_t > scan_devices() const
Scans for devices on the bus.
Definition master.hpp:126
enum port port() const
Returns the I2C port.
Definition master.hpp:114
std::vector< uint8_t > scan_devices(const std::chrono::duration< Rep, Period > &timeout) const
Scans for devices on the bus.
Definition master.hpp:138
void probe(uint8_t address) const
Probes for a device at the specified address.
Definition master.hpp:151
master_bus & operator=(master_bus &&)=delete
master_bus & operator=(const master_bus &)=delete
result< void > try_probe(uint8_t address, const std::chrono::duration< Rep, Period > &timeout) const
Probes for a device at the specified address.
Definition master.hpp:186
i2c_master_bus_handle_t handle() const
Returns the underlying ESP-IDF bus handle.
Definition master.hpp:111
void probe(uint8_t address, const std::chrono::duration< Rep, Period > &timeout) const
Probes for a device at the specified address.
Definition master.hpp:163
freq::hertz frequency() const
Returns the bus clock frequency in Hz.
Definition master.hpp:117
void unlock() const
Releases exclusive access to the bus.
Definition master.hpp:108
master_bus(const master_bus &)=delete
result< void > try_probe(uint8_t address) const
Probes for a device at the specified address.
Definition master.hpp:175
bool try_lock() const noexcept
Tries to acquire exclusive access without blocking.
Definition master.hpp:105
static result< std::unique_ptr< master_bus > > make(enum port port, gpio sda, gpio scl, freq::hertz frequency)
Creates a new I2C master bus.
master_bus(master_bus &&)=delete
void lock() const
Acquires exclusive access to the bus.
Definition master.hpp:102
I2C device at a specific 7-bit address with register operations.
Definition master.hpp:209
void transmit(const uint8_t *buf, size_t size)
Transmits data to the device.
Definition master.hpp:326
result< void > try_probe() const
Probes the device.
Definition master.hpp:278
result< void > try_write_register(uint8_t regHigh, uint8_t regLow, const std::vector< uint8_t > buf)
Writes data to a register.
Definition master.hpp:756
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.
Definition master.hpp:1116
result< void > try_read_register(uint8_t regHigh, uint8_t regLow, std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1249
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.
Definition master.hpp:663
result< std::vector< uint8_t > > try_receive(size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:496
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.
Definition master.hpp:604
void write_register(uint16_t reg, const uint8_t *buf, size_t size)
Writes data to a register.
Definition master.hpp:589
void write_registers(std::vector< uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
Definition master.hpp:859
std::vector< uint8_t > read_register(uint16_t reg, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:978
void write_register(uint8_t regHigh, uint8_t regLow, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:699
void read_register(uint8_t regHigh, uint8_t regLow, uint8_t *buf, size_t size)
Reads data from a register.
Definition master.hpp:1167
void receive(std::vector< uint8_t > buf)
Receives data from the device.
Definition master.hpp:459
result< std::vector< uint8_t > > try_read_register(uint16_t reg, size_t size)
Reads data from a register.
Definition master.hpp:1045
result< void > try_write_register(uint8_t regHigh, uint8_t regLow, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:771
result< void > try_write_registers(std::vector< uint16_t > registers, const std::vector< uint8_t > buf)
Writes data to multiple registers.
Definition master.hpp:893
result< void > try_read_register(uint16_t reg, std::vector< uint8_t > &buf)
Reads data from a register.
Definition master.hpp:1073
result< void > try_read_register(uint8_t regHigh, uint8_t regLow, uint8_t *buf, size_t size)
Reads data from a register.
Definition master.hpp:1268
std::vector< uint8_t > read_register(uint8_t regHigh, uint8_t regLow, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1152
void transmit(const std::vector< uint8_t > data)
Transmits data to the device.
Definition master.hpp:301
result< void > try_write_registers(std::vector< uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
Definition master.hpp:939
result< void > try_transmit(const std::vector< uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
Definition master.hpp:365
void receive(uint8_t *buf, size_t size)
Receives data from the device.
Definition master.hpp:434
void probe() const
Probes the device.
Definition master.hpp:257
result< void > try_transmit(const std::vector< uint8_t > data)
Transmits data to the device.
Definition master.hpp:351
void write_register(uint8_t regHigh, uint8_t regLow, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:736
void receive(std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:472
result< void > try_write_register(uint8_t regHigh, uint8_t regLow, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:806
void receive(uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:447
result< void > try_receive(uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:524
void probe(const std::chrono::duration< Rep, Period > &timeout) const
Probes the device.
Definition master.hpp:268
result< std::vector< uint8_t > > try_read_register(uint8_t regHigh, uint8_t regLow, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1220
result< std::vector< uint8_t > > try_receive(size_t size)
Receives data from the device.
Definition master.hpp:484
master_device(master_device &&)=delete
void read_register(uint16_t reg, std::vector< uint8_t > buf)
Reads data from a register.
Definition master.hpp:991
void read_register(uint8_t regHigh, uint8_t regLow, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1184
result< void > try_write_registers(std::vector< uint16_t > registers, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
Definition master.hpp:907
void write_register(uint16_t reg, const std::vector< uint8_t > buf)
Writes data to a register.
Definition master.hpp:561
master_device(const master_device &)=delete
result< std::vector< uint8_t > > try_read_register(uint8_t regHigh, uint8_t regLow, size_t size)
Reads data from a register.
Definition master.hpp:1204
result< void > try_read_register(uint8_t regHigh, uint8_t regLow, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1284
void write_register(uint16_t reg, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:575
result< void > try_write_registers(std::vector< uint16_t > registers, const uint8_t *buf, size_t size)
Writes data to multiple registers.
Definition master.hpp:924
void write_registers(std::vector< uint16_t > registers, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
Definition master.hpp:841
result< void > try_read_register(uint16_t reg, std::vector< uint8_t > &buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1087
void write_registers(std::vector< uint16_t > registers, const std::vector< uint8_t > buf)
Writes data to multiple registers.
Definition master.hpp:826
master_device(std::shared_ptr< master_bus > bus, uint8_t address)
Creates a new device on the specified bus.
static result< std::unique_ptr< master_device > > make(std::shared_ptr< master_bus > bus, uint8_t address)
Creates a new device on the specified bus.
result< void > try_receive(std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:547
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.
Definition master.hpp:1060
result< void > try_receive(std::vector< uint8_t > buf)
Receives data from the device.
Definition master.hpp:535
void read_register(uint16_t reg, uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1032
result< void > try_write_register(uint16_t reg, const std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Writes data to a register.
Definition master.hpp:631
result< void > try_transmit(const uint8_t *buf, size_t size)
Transmits data to the device.
Definition master.hpp:377
result< void > try_read_register(uint8_t regHigh, uint8_t regLow, std::vector< uint8_t > buf)
Reads data from a register.
Definition master.hpp:1234
uint8_t address() const
Returns the 7-bit device address.
Definition master.hpp:248
const std::shared_ptr< master_bus > & bus() const
Returns the parent bus.
Definition master.hpp:242
result< void > try_receive(uint8_t *buf, size_t size)
Receives data from the device.
Definition master.hpp:509
void write_registers(std::vector< uint16_t > registers, const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Writes data to multiple registers.
Definition master.hpp:875
i2c_master_dev_handle_t handle() const
Returns the underlying ESP-IDF device handle.
Definition master.hpp:245
void transmit(const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
Definition master.hpp:339
result< void > try_write_register(uint16_t reg, const uint8_t *buf, size_t size)
Writes data to a register.
Definition master.hpp:648
result< void > try_read_register(uint16_t reg, uint8_t *buf, size_t size)
Reads data from a register.
Definition master.hpp:1100
result< void > try_transmit(const uint8_t *buf, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
Definition master.hpp:392
std::vector< uint8_t > receive(size_t size)
Receives data from the device.
Definition master.hpp:407
std::vector< uint8_t > read_register(uint16_t reg, size_t size)
Reads data from a register.
Definition master.hpp:960
void read_register(uint16_t reg, std::vector< uint8_t > buf, const std::chrono::duration< Rep, Period > &timeout)
Reads data from a register.
Definition master.hpp:1004
std::vector< uint8_t > read_register(uint8_t regHigh, uint8_t regLow, size_t size)
Reads data from a register.
Definition master.hpp:1133
std::vector< uint8_t > receive(size_t size, const std::chrono::duration< Rep, Period > &timeout)
Receives data from the device.
Definition master.hpp:421
result< void > try_write_register(uint16_t reg, const std::vector< uint8_t > buf)
Writes data to a register.
Definition master.hpp:617
master_device & operator=(const master_device &)=delete
void write_register(uint8_t regHigh, uint8_t regLow, const uint8_t *buf, size_t size)
Writes data to a register.
Definition master.hpp:719
result< void > try_probe(const std::chrono::duration< Rep, Period > &timeout) const
Probes the device.
Definition master.hpp:288
master_device & operator=(master_device &&)=delete
void read_register(uint16_t reg, uint8_t *buf, size_t size)
Reads data from a register.
Definition master.hpp:1018
void transmit(const std::vector< uint8_t > data, const std::chrono::duration< Rep, Period > &timeout)
Transmits data to the device.
Definition master.hpp:313
result< void > try_write_register(uint8_t regHigh, uint8_t regLow, const uint8_t *buf, size_t size)
Writes data to a register.
Definition master.hpp:790
void write_register(uint8_t regHigh, uint8_t regLow, const std::vector< uint8_t > buf)
Writes data to a register.
Definition master.hpp:683
std::string to_string(core_id c)
Returns a string representation of a CPU core identifier.
Definition cpu.hpp:52
struct i2c_master_bus_t * i2c_master_bus_handle_t
Definition master.hpp:31
struct i2c_master_dev_t * i2c_master_dev_handle_t
Definition master.hpp:32
port
I2C port identifiers.
Definition master.hpp:47
static constexpr auto DEFAULT_TIMEOUT
Default timeout for I2C operations.
Definition master.hpp:41
@ i2c0
I2C port 0.
I2C master driver classes.
Definition master.hpp:38
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:237
@ timeout
Operation timed out.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:118