libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32I2C Class Reference

STM32 I2C 驱动实现 / STM32 I2C driver implementation. More...

#include <stm32_i2c.hpp>

Inheritance diagram for LibXR::STM32I2C:
[legend]
Collaboration diagram for LibXR::STM32I2C:
[legend]

Data Structures

struct  HasClockSpeed
 
struct  HasClockSpeed< T, std::void_t< decltype(std::declval< T >() ->Init.ClockSpeed)> >
 

Public Member Functions

 STM32I2C (I2C_HandleTypeDef *hi2c, RawData dma_buff, uint32_t dma_enable_min_size=3)
 构造 I2C 对象 / Construct I2C object
 
ErrorCode Read (uint16_t slave_addr, RawData read_data, ReadOperation &op, bool in_isr) override
 读取 I2C 设备的数据。 Reads data from an I2C device.
 
ErrorCode Write (uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr) override
 I2C 设备写入数据。 Writes data to an I2C device.
 
ErrorCode MemRead (uint16_t slave_addr, uint16_t mem_addr, RawData read_data, ReadOperation &op, MemAddrLength mem_addr_size, bool in_isr) 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, bool in_isr) override
 I2C 设备指定寄存器写入数据。 Writes data to a specific register of an I2C device.
 
template<typename T >
std::enable_if<!HasClockSpeed< T >::value >::type SetClockSpeed (T &, const Configuration &)
 
template<typename T >
std::enable_if< HasClockSpeed< T >::value >::type SetClockSpeed (T &i2c_handle, const Configuration &config)
 
ErrorCode SetConfig (Configuration config) override
 配置 I2C 设备参数。 Configures the I2C device settings.
 
- Public Member Functions inherited from LibXR::I2C
 I2C ()
 默认构造函数。 Default constructor.
 

Data Fields

stm32_i2c_id_t id_
 
I2C_HandleTypeDef * i2c_handle_
 
uint32_t dma_enable_min_size_
 
RawData dma_buff_
 
ReadOperation read_op_
 
WriteOperation write_op_
 
RawData read_buff_
 
bool read_ = false
 
bool recovering_ = false
 
AsyncBlockWait block_wait_ {}
 

Static Public Attributes

static STM32I2Cmap [STM32_I2C_NUMBER] = {nullptr}
 

Additional Inherited Members

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

Detailed Description

STM32 I2C 驱动实现 / STM32 I2C driver implementation.

Definition at line 51 of file stm32_i2c.hpp.

Constructor & Destructor Documentation

◆ STM32I2C()

STM32I2C::STM32I2C ( I2C_HandleTypeDef * hi2c,
RawData dma_buff,
uint32_t dma_enable_min_size = 3 )

构造 I2C 对象 / Construct I2C object

Definition at line 155 of file stm32_i2c.cpp.

157 : I2C(),
158 id_(STM32_I2C_GetID(hi2c->Instance)),
159 i2c_handle_(hi2c),
160 dma_enable_min_size_(dma_enable_min_size),
161 dma_buff_(dma_buff)
162{
163 map[id_] = this;
164}
I2C()
默认构造函数。 Default constructor.
Definition i2c.hpp:39

Member Function Documentation

◆ MemRead()

ErrorCode STM32I2C::MemRead ( uint16_t slave_addr,
uint16_t mem_addr,
RawData read_data,
ReadOperation & op,
MemAddrLength mem_addr_size,
bool in_isr )
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 283 of file stm32_i2c.cpp.

285{
286 ASSERT(read_data.size_ <= dma_buff_.size_);
287
288 if (i2c_handle_->State != HAL_I2C_STATE_READY)
289 {
290 return ErrorCode::BUSY;
291 }
292
293 read_ = true;
294
295 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
296
297 if (read_data.size_ > dma_enable_min_size_)
298 {
299 read_op_ = op;
300 read_buff_ = read_data;
301 if (op.type == ReadOperation::OperationType::BLOCK)
302 {
303 // Arm the BLOCK waiter before HAL exposes completion to IRQ context.
304 block_wait_.Start(*op.data.sem_info.sem);
305 }
306 const HAL_StatusTypeDef st = HAL_I2C_Mem_Read_DMA(
307 i2c_handle_, dev_addr, mem_addr,
308 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
309 : I2C_MEMADD_SIZE_16BIT,
310 reinterpret_cast<uint8_t*>(dma_buff_.addr_), read_data.size_);
311 if (st != HAL_OK)
312 {
313 if (op.type == ReadOperation::OperationType::BLOCK)
314 {
315 block_wait_.Cancel();
316 return MapHalStartFailure(i2c_handle_, st);
317 }
318 return ErrorCode::BUSY;
319 }
320 op.MarkAsRunning();
321 if (op.type == ReadOperation::OperationType::BLOCK)
322 {
323 return WaitBlockResultAndRecoverTimeout(this, op.data.sem_info.timeout);
324 }
325 return ErrorCode::OK;
326 }
327 else
328 {
329 auto ans =
330 HAL_I2C_Mem_Read(i2c_handle_, dev_addr, mem_addr,
331 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
332 : I2C_MEMADD_SIZE_16BIT,
333 reinterpret_cast<uint8_t*>(read_data.addr_), read_data.size_,
334 20) == HAL_OK
337
338 if (op.type != ReadOperation::OperationType::BLOCK)
339 {
340 op.UpdateStatus(in_isr, ans);
341 }
342 return ans;
343 }
344}
union LibXR::Operation::@5 data
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
Definition libxr_rw.hpp:178
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Definition libxr_rw.hpp:213
OperationType type
Definition libxr_rw.hpp:237
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
@ BUSY
忙碌 | Busy
@ OK
操作成功 | Operation successful

◆ MemWrite()

ErrorCode STM32I2C::MemWrite ( uint16_t slave_addr,
uint16_t mem_addr,
ConstRawData write_data,
WriteOperation & op,
MemAddrLength mem_addr_size,
bool in_isr )
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 346 of file stm32_i2c.cpp.

349{
350 ASSERT(write_data.size_ <= dma_buff_.size_);
351
352 if (i2c_handle_->State != HAL_I2C_STATE_READY)
353 {
354 return ErrorCode::BUSY;
355 }
356
357 read_ = false;
358
359 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
360
361 Memory::FastCopy(dma_buff_.addr_, write_data.addr_, write_data.size_);
362
363 if (write_data.size_ > dma_enable_min_size_)
364 {
365 write_op_ = op;
366 if (op.type == WriteOperation::OperationType::BLOCK)
367 {
368 // Arm the BLOCK waiter before HAL exposes completion to IRQ context.
369 block_wait_.Start(*op.data.sem_info.sem);
370 }
371#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
372 SCB_CleanDCache_by_Addr(reinterpret_cast<uint32_t*>(dma_buff_.addr_),
373 write_data.size_);
374#endif
375 const HAL_StatusTypeDef st = HAL_I2C_Mem_Write_DMA(
376 i2c_handle_, dev_addr, mem_addr,
377 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
378 : I2C_MEMADD_SIZE_16BIT,
379 reinterpret_cast<uint8_t*>(dma_buff_.addr_), write_data.size_);
380 if (st != HAL_OK)
381 {
382 if (op.type == WriteOperation::OperationType::BLOCK)
383 {
384 block_wait_.Cancel();
385 return MapHalStartFailure(i2c_handle_, st);
386 }
387 return ErrorCode::BUSY;
388 }
389 op.MarkAsRunning();
390 if (op.type == WriteOperation::OperationType::BLOCK)
391 {
392 return WaitBlockResultAndRecoverTimeout(this, op.data.sem_info.timeout);
393 }
394 return ErrorCode::OK;
395 }
396 else
397 {
398 auto ans =
399 HAL_I2C_Mem_Write(i2c_handle_, dev_addr, mem_addr,
400 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
401 : I2C_MEMADD_SIZE_16BIT,
402 reinterpret_cast<uint8_t*>(dma_buff_.addr_), write_data.size_,
403 20) == HAL_OK
406
407 if (op.type != WriteOperation::OperationType::BLOCK)
408 {
409 op.UpdateStatus(in_isr, ans);
410 }
411 return ans;
412 }
413}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:5

◆ Read()

ErrorCode STM32I2C::Read ( uint16_t slave_addr,
RawData read_data,
ReadOperation & op,
bool in_isr )
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 166 of file stm32_i2c.cpp.

168{
169 if (i2c_handle_->State != HAL_I2C_STATE_READY)
170 {
171 return ErrorCode::BUSY;
172 }
173
174 read_ = true;
175
176 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
177
178 if (read_data.size_ > dma_enable_min_size_)
179 {
180 read_op_ = op;
181 read_buff_ = read_data;
182 if (op.type == ReadOperation::OperationType::BLOCK)
183 {
184 // Arm the BLOCK waiter before HAL exposes completion to IRQ context.
185 block_wait_.Start(*op.data.sem_info.sem);
186 }
187 const HAL_StatusTypeDef st = HAL_I2C_Master_Receive_DMA(
188 i2c_handle_, dev_addr, reinterpret_cast<uint8_t*>(dma_buff_.addr_),
189 read_data.size_);
190 if (st != HAL_OK)
191 {
192 if (op.type == ReadOperation::OperationType::BLOCK)
193 {
194 block_wait_.Cancel();
195 return MapHalStartFailure(i2c_handle_, st);
196 }
197 return ErrorCode::BUSY;
198 }
199 op.MarkAsRunning();
200 if (op.type == ReadOperation::OperationType::BLOCK)
201 {
202 return WaitBlockResultAndRecoverTimeout(this, op.data.sem_info.timeout);
203 }
204 return ErrorCode::OK;
205 }
206 else
207 {
208 auto ans = HAL_I2C_Master_Receive(i2c_handle_, dev_addr,
209 reinterpret_cast<uint8_t*>(read_data.addr_),
210 read_data.size_, 20) == HAL_OK
213 // BLOCK 模式下沿用统一状态更新路径。
214 // Reuse the same status update path for BLOCK mode.
215 if (op.type != ReadOperation::OperationType::BLOCK)
216 {
217 op.UpdateStatus(in_isr, ans);
218 }
219 return ans;
220 }
221}

◆ SetClockSpeed() [1/2]

template<typename T >
std::enable_if<!HasClockSpeed< T >::value >::type LibXR::STM32I2C::SetClockSpeed ( T & ,
const Configuration &  )
inline

Definition at line 84 of file stm32_i2c.hpp.

86 {
87 }

◆ SetClockSpeed() [2/2]

template<typename T >
std::enable_if< HasClockSpeed< T >::value >::type LibXR::STM32I2C::SetClockSpeed ( T & i2c_handle,
const Configuration & config )
inline

Definition at line 90 of file stm32_i2c.hpp.

92 {
93 i2c_handle->Init.ClockSpeed = config.clock_speed;
94 }

◆ SetConfig()

ErrorCode STM32I2C::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 415 of file stm32_i2c.cpp.

416{
417 if (HasClockSpeed<decltype(i2c_handle_)>::value)
418 {
419 SetClockSpeed<decltype(i2c_handle_)>(i2c_handle_, config);
420 }
421 else
422 {
424 }
425
426 if (HAL_I2C_Init(i2c_handle_) != HAL_OK)
427 {
428 return ErrorCode::INIT_ERR;
429 }
430 return ErrorCode::OK;
431}
@ INIT_ERR
初始化错误 | Initialization error
@ NOT_SUPPORT
不支持 | Not supported

◆ Write()

ErrorCode STM32I2C::Write ( uint16_t slave_addr,
ConstRawData write_data,
WriteOperation & op,
bool in_isr )
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 223 of file stm32_i2c.cpp.

225{
226 if (i2c_handle_->State != HAL_I2C_STATE_READY)
227 {
228 return ErrorCode::BUSY;
229 }
230
231 read_ = false;
232
233 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
234
235 Memory::FastCopy(dma_buff_.addr_, write_data.addr_, write_data.size_);
236
237 if (write_data.size_ > dma_enable_min_size_)
238 {
239 write_op_ = op;
240 if (op.type == WriteOperation::OperationType::BLOCK)
241 {
242 // Arm the BLOCK waiter before HAL exposes completion to IRQ context.
243 block_wait_.Start(*op.data.sem_info.sem);
244 }
245#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
246 SCB_CleanDCache_by_Addr(reinterpret_cast<uint32_t*>(dma_buff_.addr_),
247 write_data.size_);
248#endif
249 const HAL_StatusTypeDef st = HAL_I2C_Master_Transmit_DMA(
250 i2c_handle_, dev_addr, reinterpret_cast<uint8_t*>(dma_buff_.addr_),
251 write_data.size_);
252 if (st != HAL_OK)
253 {
254 if (op.type == WriteOperation::OperationType::BLOCK)
255 {
256 block_wait_.Cancel();
257 return MapHalStartFailure(i2c_handle_, st);
258 }
259 return ErrorCode::BUSY;
260 }
261 op.MarkAsRunning();
262 if (op.type == WriteOperation::OperationType::BLOCK)
263 {
264 return WaitBlockResultAndRecoverTimeout(this, op.data.sem_info.timeout);
265 }
266 return ErrorCode::OK;
267 }
268 else
269 {
270 auto ans = HAL_I2C_Master_Transmit(i2c_handle_, dev_addr,
271 reinterpret_cast<uint8_t*>(dma_buff_.addr_),
272 write_data.size_, 20) == HAL_OK
275 if (op.type != WriteOperation::OperationType::BLOCK)
276 {
277 op.UpdateStatus(in_isr, ans);
278 }
279 return ans;
280 }
281}

Field Documentation

◆ block_wait_

AsyncBlockWait LibXR::STM32I2C::block_wait_ {}

Definition at line 110 of file stm32_i2c.hpp.

110{};

◆ dma_buff_

RawData LibXR::STM32I2C::dma_buff_

Definition at line 102 of file stm32_i2c.hpp.

◆ dma_enable_min_size_

uint32_t LibXR::STM32I2C::dma_enable_min_size_

Definition at line 100 of file stm32_i2c.hpp.

◆ i2c_handle_

I2C_HandleTypeDef* LibXR::STM32I2C::i2c_handle_

Definition at line 99 of file stm32_i2c.hpp.

◆ id_

stm32_i2c_id_t LibXR::STM32I2C::id_

Definition at line 98 of file stm32_i2c.hpp.

◆ map

STM32I2C * STM32I2C::map = {nullptr}
static

Definition at line 112 of file stm32_i2c.hpp.

◆ read_

bool LibXR::STM32I2C::read_ = false

Definition at line 108 of file stm32_i2c.hpp.

◆ read_buff_

RawData LibXR::STM32I2C::read_buff_

Definition at line 106 of file stm32_i2c.hpp.

◆ read_op_

ReadOperation LibXR::STM32I2C::read_op_

Definition at line 104 of file stm32_i2c.hpp.

◆ recovering_

bool LibXR::STM32I2C::recovering_ = false

Definition at line 109 of file stm32_i2c.hpp.

◆ write_op_

WriteOperation LibXR::STM32I2C::write_op_

Definition at line 105 of file stm32_i2c.hpp.


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