libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::ESP32I2C Class Reference
Inheritance diagram for LibXR::ESP32I2C:
[legend]
Collaboration diagram for LibXR::ESP32I2C:
[legend]

Public Member Functions

 ESP32I2C (i2c_port_t port_num, int scl_pin, int sda_pin, uint32_t clock_speed=400000U, bool enable_internal_pullup=true, uint32_t timeout_ms=100U, uint32_t isr_enable_min_size=32U)
 
ErrorCode Read (uint16_t slave_addr, RawData read_data, ReadOperation &op, bool in_isr=false) override
 读取 I2C 设备的数据。 Reads data from an I2C device.
 
ErrorCode Write (uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr=false) override
 向 I2C 设备写入数据。 Writes data to an I2C device.
 
ErrorCode SetConfig (Configuration config) override
 配置 I2C 设备参数。 Configures the I2C device settings.
 
ErrorCode MemRead (uint16_t slave_addr, uint16_t mem_addr, RawData read_data, ReadOperation &op, MemAddrLength mem_addr_size=MemAddrLength::BYTE_8, bool in_isr=false) override
 从 I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.
 
ErrorCode MemWrite (uint16_t slave_addr, uint16_t mem_addr, ConstRawData write_data, WriteOperation &op, MemAddrLength mem_addr_size=MemAddrLength::BYTE_8, bool in_isr=false) override
 向 I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.
 
i2c_port_t Port () const
 
- Public Member Functions inherited from LibXR::I2C
 I2C ()
 默认构造函数。 Default constructor.
 

Static Public Attributes

static constexpr int PIN_NO_CHANGE = -1
 

Additional Inherited Members

- Public Types inherited from LibXR::I2C
enum class  MemAddrLength : uint8_t { BYTE_8 , BYTE_16 }
 

Detailed Description

Definition at line 20 of file esp_i2c.hpp.

Constructor & Destructor Documentation

◆ ESP32I2C()

LibXR::ESP32I2C::ESP32I2C ( i2c_port_t port_num,
int scl_pin,
int sda_pin,
uint32_t clock_speed = 400000U,
bool enable_internal_pullup = true,
uint32_t timeout_ms = 100U,
uint32_t isr_enable_min_size = 32U )

Definition at line 135 of file esp_i2c.cpp.

138 : port_num_(port_num),
139 scl_pin_(scl_pin),
140 sda_pin_(sda_pin),
141 enable_internal_pullup_(enable_internal_pullup),
142 timeout_ms_(timeout_ms),
143 isr_enable_min_size_(isr_enable_min_size),
144 config_{clock_speed}
145{
146 ASSERT(port_num_ >= 0);
147 ASSERT(port_num_ < SOC_I2C_NUM);
148 ASSERT(GPIO_IS_VALID_OUTPUT_GPIO(static_cast<gpio_num_t>(scl_pin_)));
149 ASSERT(GPIO_IS_VALID_OUTPUT_GPIO(static_cast<gpio_num_t>(sda_pin_)));
150 ASSERT(config_.clock_speed > 0U);
151 static_assert(FIFO_LEN > 2U);
152
153 if (InitHardware() != ErrorCode::OK)
154 {
155 REQUIRE(false);
156 return;
157 }
158}
@ OK
操作成功 / Operation successful
uint32_t clock_speed
I2C 通信时钟速率(单位:Hz) / The I2C clock speed (in Hz).
Definition i2c.hpp:26

Member Function Documentation

◆ MemRead()

ErrorCode LibXR::ESP32I2C::MemRead ( uint16_t slave_addr,
uint16_t mem_addr,
RawData read_data,
ReadOperation & op,
MemAddrLength mem_addr_size = MemAddrLength::BYTE_8,
bool in_isr = false )
overridevirtual

从 I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.

该函数从指定 I2C 从设备的寄存器地址读取数据,并存储到 read_data 中。 This function reads data from the specified register of the I2C slave and stores it in read_data.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
mem_addr寄存器地址(通常为 8 位或 16 位)。 Register address (typically 8-bit or 16-bit).
read_data用于存储读取数据的 RawData 对象。 RawData object to store read data.
op异步或同步的读取操作对象。 Read operation object (sync or async).
mem_addr_size寄存器地址长度。 Size of register address in bytes.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,表示是否读取成功。 Returns ErrorCode indicating success or failure.

Implements LibXR::I2C.

Definition at line 1273 of file esp_i2c.cpp.

1275{
1276 const ErrorCode init_ec = EnsureInitialized(in_isr);
1277 if (init_ec != ErrorCode::OK)
1278 {
1279 return Complete(op, in_isr, init_ec);
1280 }
1281
1282 if (!IsValid7BitAddr(slave_addr))
1283 {
1284 return Complete(op, in_isr, ErrorCode::ARG_ERR);
1285 }
1286
1287 if ((read_data.size_ > 0U) && (read_data.addr_ == nullptr))
1288 {
1289 return Complete(op, in_isr, ErrorCode::PTR_NULL);
1290 }
1291
1292 const size_t mem_len = MemAddrBytes(mem_addr_size);
1293 if (mem_len > MAX_WRITE_READ_PREFIX)
1294 {
1295 return Complete(op, in_isr, ErrorCode::SIZE_ERR);
1296 }
1297
1298 if (!Acquire())
1299 {
1300 return Complete(op, in_isr, ErrorCode::BUSY);
1301 }
1302
1303 std::array<uint8_t, 2> mem_raw = {};
1304 EncodeMemAddr(mem_addr, mem_len, mem_raw.data());
1305
1306 auto* dst = static_cast<uint8_t*>(read_data.addr_);
1307 const size_t total_size = mem_len + read_data.size_;
1308 if ((read_data.size_ > 0U) && ShouldUseInterruptAsync(total_size))
1309 {
1310 if (op.type == ReadOperation::OperationType::BLOCK)
1311 {
1312 block_wait_.Start(*op.data.sem_info.sem);
1313 }
1314 const ErrorCode ans =
1315 StartAsyncTransaction(slave_addr, mem_raw.data(), mem_len, nullptr, 0U, dst,
1316 read_data.size_, op, in_isr);
1317 if (ans != ErrorCode::OK)
1318 {
1319 if (op.type == ReadOperation::OperationType::BLOCK)
1320 {
1321 block_wait_.Cancel();
1322 }
1323 Release();
1324 return Complete(op, in_isr, ans);
1325 }
1326 if (op.type == ReadOperation::OperationType::BLOCK)
1327 {
1328 ASSERT(!in_isr);
1329 return block_wait_.Wait(op.data.sem_info.timeout);
1330 }
1331 return ErrorCode::OK;
1332 }
1333
1334 size_t offset = 0U;
1336
1337 while (offset < read_data.size_)
1338 {
1339 const size_t chunk = std::min(read_data.size_ - offset, MAX_READ_PAYLOAD);
1340 const uint16_t cur_mem = static_cast<uint16_t>(mem_addr + offset);
1341 EncodeMemAddr(cur_mem, mem_len, mem_raw.data());
1342
1343 ans = ExecuteTransaction(slave_addr, mem_raw.data(), mem_len, dst + offset, chunk,
1344 in_isr);
1345 if (ans != ErrorCode::OK)
1346 {
1347 break;
1348 }
1349 offset += chunk;
1350 }
1351
1352 Release();
1353 return Complete(op, in_isr, ans);
1354}
void Start(Semaphore &sem)
绑定信号量并开始等待 / Bind a semaphore and start waiting.
ErrorCode Wait(uint32_t timeout)
等待完成或超时交接 / Wait for completion or a timeout handoff.
void Cancel()
清除等待状态,不发送通知 / Clear the wait state without posting.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ SIZE_ERR
尺寸错误 / Size error
@ BUSY
忙碌 / Busy
@ PTR_NULL
空指针 / Null pointer
@ ARG_ERR
参数错误 / Argument error

◆ MemWrite()

ErrorCode LibXR::ESP32I2C::MemWrite ( uint16_t slave_addr,
uint16_t mem_addr,
ConstRawData write_data,
WriteOperation & op,
MemAddrLength mem_addr_size = MemAddrLength::BYTE_8,
bool in_isr = false )
overridevirtual

向 I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.

该函数将 write_data 写入指定 I2C 从设备的寄存器地址。 This function writes write_data to the specified register of the I2C slave.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
mem_addr寄存器地址(通常为 8 位或 16 位)。 Register address (typically 8-bit or 16-bit).
write_data要写入的数据,ConstRawData 类型。 Data to be written, of type ConstRawData.
op异步或同步的写入操作对象。 Write operation object (sync or async).
mem_addr_size寄存器地址长度。 Size of register address in bytes.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,表示是否写入成功。 Returns ErrorCode indicating success or failure.

Implements LibXR::I2C.

Definition at line 1178 of file esp_i2c.cpp.

1181{
1182 const ErrorCode init_ec = EnsureInitialized(in_isr);
1183 if (init_ec != ErrorCode::OK)
1184 {
1185 return Complete(op, in_isr, init_ec);
1186 }
1187
1188 if (!IsValid7BitAddr(slave_addr))
1189 {
1190 return Complete(op, in_isr, ErrorCode::ARG_ERR);
1191 }
1192
1193 if ((write_data.size_ > 0U) && (write_data.addr_ == nullptr))
1194 {
1195 return Complete(op, in_isr, ErrorCode::PTR_NULL);
1196 }
1197
1198 const size_t mem_len = MemAddrBytes(mem_addr_size);
1199 if (mem_len > MAX_WRITE_PAYLOAD)
1200 {
1201 return Complete(op, in_isr, ErrorCode::SIZE_ERR);
1202 }
1203
1204 if (!Acquire())
1205 {
1206 return Complete(op, in_isr, ErrorCode::BUSY);
1207 }
1208
1209 std::array<uint8_t, 2> mem_raw = {};
1210 EncodeMemAddr(mem_addr, mem_len, mem_raw.data());
1211
1212 const size_t total_size = mem_len + write_data.size_;
1213 if (ShouldUseInterruptAsync(total_size))
1214 {
1215 if (op.type == WriteOperation::OperationType::BLOCK)
1216 {
1217 block_wait_.Start(*op.data.sem_info.sem);
1218 }
1219 const ErrorCode ans =
1220 StartAsyncTransaction(slave_addr, mem_raw.data(), mem_len,
1221 static_cast<const uint8_t*>(write_data.addr_),
1222 write_data.size_, nullptr, 0U, op, in_isr);
1223 if (ans != ErrorCode::OK)
1224 {
1225 if (op.type == WriteOperation::OperationType::BLOCK)
1226 {
1227 block_wait_.Cancel();
1228 }
1229 Release();
1230 return Complete(op, in_isr, ans);
1231 }
1232 if (op.type == WriteOperation::OperationType::BLOCK)
1233 {
1234 ASSERT(!in_isr);
1235 return block_wait_.Wait(op.data.sem_info.timeout);
1236 }
1237 return ErrorCode::OK;
1238 }
1239
1240 std::array<uint8_t, FIFO_LEN> staging = {};
1241 const size_t max_chunk = MAX_WRITE_PAYLOAD - mem_len;
1242 auto* src = static_cast<const uint8_t*>(write_data.addr_);
1243 size_t offset = 0U;
1245
1246 if (write_data.size_ == 0U)
1247 {
1248 EncodeMemAddr(mem_addr, mem_len, staging.data());
1249 ans = ExecuteTransaction(slave_addr, staging.data(), mem_len, nullptr, 0U, in_isr);
1250 }
1251 else
1252 {
1253 while (offset < write_data.size_)
1254 {
1255 const size_t chunk = std::min(write_data.size_ - offset, max_chunk);
1256 const uint16_t cur_mem = static_cast<uint16_t>(mem_addr + offset);
1257 EncodeMemAddr(cur_mem, mem_len, staging.data());
1258 Memory::FastCopy(staging.data() + mem_len, src + offset, chunk);
1259 ans = ExecuteTransaction(slave_addr, staging.data(), mem_len + chunk, nullptr, 0U,
1260 in_isr);
1261 if (ans != ErrorCode::OK)
1262 {
1263 break;
1264 }
1265 offset += chunk;
1266 }
1267 }
1268
1269 Release();
1270 return Complete(op, in_isr, ans);
1271}
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy

◆ Port()

i2c_port_t LibXR::ESP32I2C::Port ( ) const
inline

Definition at line 47 of file esp_i2c.hpp.

47{ return port_num_; }

◆ Read()

ErrorCode LibXR::ESP32I2C::Read ( uint16_t slave_addr,
RawData read_data,
ReadOperation & op,
bool in_isr = false )
overridevirtual

读取 I2C 设备的数据。 Reads data from an I2C device.

该函数从指定的 I2C 从设备地址读取数据,并存储到 read_data 中。 This function reads data from the specified I2C slave address and stores it in read_data.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
read_data存储读取数据的 RawData 对象。 A RawData object to store the read data.
op读取操作对象,包含同步或异步操作模式。 Read operation object containing synchronous or asynchronous operation mode.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,指示操作是否成功。 Returns an ErrorCode indicating whether the operation was successful.

Implements LibXR::I2C.

Definition at line 1120 of file esp_i2c.cpp.

1122{
1123 const ErrorCode init_ec = EnsureInitialized(in_isr);
1124 if (init_ec != ErrorCode::OK)
1125 {
1126 return Complete(op, in_isr, init_ec);
1127 }
1128
1129 if (!IsValid7BitAddr(slave_addr))
1130 {
1131 return Complete(op, in_isr, ErrorCode::ARG_ERR);
1132 }
1133
1134 if ((read_data.size_ > 0U) && (read_data.addr_ == nullptr))
1135 {
1136 return Complete(op, in_isr, ErrorCode::PTR_NULL);
1137 }
1138
1139 if (!Acquire())
1140 {
1141 return Complete(op, in_isr, ErrorCode::BUSY);
1142 }
1143
1144 const size_t total_size = read_data.size_;
1145 if (ShouldUseInterruptAsync(total_size))
1146 {
1147 if (op.type == ReadOperation::OperationType::BLOCK)
1148 {
1149 block_wait_.Start(*op.data.sem_info.sem);
1150 }
1151 const ErrorCode ans = StartAsyncTransaction(slave_addr, nullptr, 0U, nullptr, 0U,
1152 static_cast<uint8_t*>(read_data.addr_),
1153 read_data.size_, op, in_isr);
1154 if (ans != ErrorCode::OK)
1155 {
1156 if (op.type == ReadOperation::OperationType::BLOCK)
1157 {
1158 block_wait_.Cancel();
1159 }
1160 Release();
1161 return Complete(op, in_isr, ans);
1162 }
1163 if (op.type == ReadOperation::OperationType::BLOCK)
1164 {
1165 ASSERT(!in_isr);
1166 return block_wait_.Wait(op.data.sem_info.timeout);
1167 }
1168 return ErrorCode::OK;
1169 }
1170
1171 const ErrorCode ans =
1172 ExecuteTransaction(slave_addr, nullptr, 0U, static_cast<uint8_t*>(read_data.addr_),
1173 read_data.size_, in_isr);
1174 Release();
1175 return Complete(op, in_isr, ans);
1176}

◆ SetConfig()

ErrorCode LibXR::ESP32I2C::SetConfig ( Configuration config)
overridevirtual

配置 I2C 设备参数。 Configures the I2C device settings.

该函数用于设置 I2C 设备的参数,例如通信速率等。 This function sets the parameters of the I2C device, such as the communication speed.

Parameters
config包含 I2C 设置信息的 Configuration 结构体。 A Configuration structure containing I2C settings.
Returns
返回 ErrorCode,指示配置是否成功。 Returns an ErrorCode indicating whether the configuration was successful.

Implements LibXR::I2C.

Definition at line 1024 of file esp_i2c.cpp.

1025{
1026 if (config.clock_speed == 0U)
1027 {
1028 return ErrorCode::ARG_ERR;
1029 }
1030
1031 if (!initialized_)
1032 {
1033 const ErrorCode init_err = InitHardware();
1034 if (init_err != ErrorCode::OK)
1035 {
1036 return init_err;
1037 }
1038 }
1039
1040 if (!Acquire())
1041 {
1042 return ErrorCode::BUSY;
1043 }
1044
1045 if (i2c_ll_is_bus_busy(hal_.dev))
1046 {
1047 Release();
1048 return ErrorCode::BUSY;
1049 }
1050
1051 const Configuration previous_config = config_;
1052 config_ = config;
1053 const ErrorCode ans = ApplyConfig();
1054 if (ans != ErrorCode::OK)
1055 {
1056 config_ = previous_config;
1057 }
1058 Release();
1059 return ans;
1060}

◆ Write()

ErrorCode LibXR::ESP32I2C::Write ( uint16_t slave_addr,
ConstRawData write_data,
WriteOperation & op,
bool in_isr = false )
overridevirtual

向 I2C 设备写入数据。 Writes data to an I2C device.

该函数将 write_data 写入指定的 I2C 从设备地址。 This function writes write_data to the specified I2C slave address.

Parameters
slave_addr目标 I2C 从设备地址,不带 R/W 位。 Target I2C slave address, no R/W bit included.
write_data需要写入的数据,ConstRawData 类型。 The data to be written, of type ConstRawData.
op写入操作对象,包含同步或异步操作模式。 Write operation object containing synchronous or asynchronous operation mode.
in_isr是否在中断中进行操作 / Whether the operation is performed in an ISR.
Returns
返回 ErrorCode,指示操作是否成功。 Returns an ErrorCode indicating whether the operation was successful.

Implements LibXR::I2C.

Definition at line 1062 of file esp_i2c.cpp.

1064{
1065 const ErrorCode init_ec = EnsureInitialized(in_isr);
1066 if (init_ec != ErrorCode::OK)
1067 {
1068 return Complete(op, in_isr, init_ec);
1069 }
1070
1071 if (!IsValid7BitAddr(slave_addr))
1072 {
1073 return Complete(op, in_isr, ErrorCode::ARG_ERR);
1074 }
1075
1076 if ((write_data.size_ > 0U) && (write_data.addr_ == nullptr))
1077 {
1078 return Complete(op, in_isr, ErrorCode::PTR_NULL);
1079 }
1080
1081 if (!Acquire())
1082 {
1083 return Complete(op, in_isr, ErrorCode::BUSY);
1084 }
1085
1086 const size_t total_size = write_data.size_;
1087 if (ShouldUseInterruptAsync(total_size))
1088 {
1089 if (op.type == WriteOperation::OperationType::BLOCK)
1090 {
1091 block_wait_.Start(*op.data.sem_info.sem);
1092 }
1093 const ErrorCode ans = StartAsyncTransaction(
1094 slave_addr, nullptr, 0U, static_cast<const uint8_t*>(write_data.addr_),
1095 write_data.size_, nullptr, 0U, op, in_isr);
1096 if (ans != ErrorCode::OK)
1097 {
1098 if (op.type == WriteOperation::OperationType::BLOCK)
1099 {
1100 block_wait_.Cancel();
1101 }
1102 Release();
1103 return Complete(op, in_isr, ans);
1104 }
1105 if (op.type == WriteOperation::OperationType::BLOCK)
1106 {
1107 ASSERT(!in_isr);
1108 return block_wait_.Wait(op.data.sem_info.timeout);
1109 }
1110 return ErrorCode::OK;
1111 }
1112
1113 const ErrorCode ans =
1114 ExecuteTransaction(slave_addr, static_cast<const uint8_t*>(write_data.addr_),
1115 write_data.size_, nullptr, 0U, in_isr);
1116 Release();
1117 return Complete(op, in_isr, ans);
1118}

Member Data Documentation

◆ PIN_NO_CHANGE

int LibXR::ESP32I2C::PIN_NO_CHANGE = -1
staticconstexpr

Definition at line 23 of file esp_i2c.hpp.


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