1#include "stm32_i2c.hpp"
3#ifdef HAL_I2C_MODULE_ENABLED
7STM32I2C* STM32I2C::map[STM32_I2C_NUMBER] = {
nullptr};
9stm32_i2c_id_t STM32_I2C_GetID(I2C_TypeDef* hi2c)
13 return stm32_i2c_id_t::STM32_I2C_ID_ERROR;
16 else if (hi2c == I2C1)
18 return stm32_i2c_id_t::STM32_I2C1;
22 else if (hi2c == I2C2)
24 return stm32_i2c_id_t::STM32_I2C2;
28 else if (hi2c == I2C3)
30 return stm32_i2c_id_t::STM32_I2C3;
34 else if (hi2c == I2C4)
36 return stm32_i2c_id_t::STM32_I2C4;
40 else if (hi2c == I2C5)
42 return stm32_i2c_id_t::STM32_I2C5;
46 else if (hi2c == I2C6)
48 return stm32_i2c_id_t::STM32_I2C6;
52 else if (hi2c == I2C7)
54 return stm32_i2c_id_t::STM32_I2C7;
58 else if (hi2c == I2C8)
60 return stm32_i2c_id_t::STM32_I2C8;
63 return stm32_i2c_id_t::STM32_I2C_ID_ERROR;
72static inline uint16_t EncodeHalDevAddress(
const I2C_HandleTypeDef* hi2c,
75 ASSERT(hi2c !=
nullptr);
77#if defined(I2C_ADDRESSINGMODE_10BIT)
78 if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
80 ASSERT(slave_addr <= 0x03FF);
81 return static_cast<uint16_t
>(slave_addr & 0x03FF);
86 ASSERT(slave_addr <= 0x007F);
87 return static_cast<uint16_t
>((slave_addr & 0x007F) << 1);
93 uint32_t dma_enable_min_size)
95 id_(STM32_I2C_GetID(hi2c->Instance)),
97 dma_enable_min_size_(dma_enable_min_size),
106 if (i2c_handle_->State != HAL_I2C_STATE_READY)
108 return ErrorCode::BUSY;
113 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
115 if (read_data.
size_ > dma_enable_min_size_)
118 HAL_I2C_Master_Receive_DMA(i2c_handle_, dev_addr,
119 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_),
121 read_buff_ = read_data;
123 if (op.
type == ReadOperation::OperationType::BLOCK)
125 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
127 return ErrorCode::OK;
131 auto ans = HAL_I2C_Master_Receive(i2c_handle_, dev_addr,
132 reinterpret_cast<uint8_t*
>(read_data.
addr_),
133 read_data.
size_, 20) == HAL_OK
139 if (op.
type == ReadOperation::OperationType::BLOCK)
141 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
150 if (i2c_handle_->State != HAL_I2C_STATE_READY)
152 return ErrorCode::BUSY;
157 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
161 if (write_data.
size_ > dma_enable_min_size_)
164#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
165 SCB_CleanDCache_by_Addr(
reinterpret_cast<uint32_t*
>(dma_buff_.
addr_),
168 HAL_I2C_Master_Transmit_DMA(i2c_handle_, dev_addr,
169 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_),
172 if (op.
type == WriteOperation::OperationType::BLOCK)
174 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
176 return ErrorCode::OK;
180 auto ans = HAL_I2C_Master_Transmit(i2c_handle_, dev_addr,
181 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_),
182 write_data.
size_, 20) == HAL_OK
186 if (op.
type == WriteOperation::OperationType::BLOCK)
188 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
199 if (i2c_handle_->State != HAL_I2C_STATE_READY)
201 return ErrorCode::BUSY;
206 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
208 if (read_data.
size_ > dma_enable_min_size_)
211 HAL_I2C_Mem_Read_DMA(i2c_handle_, dev_addr, mem_addr,
212 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
213 : I2C_MEMADD_SIZE_16BIT,
214 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_), read_data.
size_);
215 read_buff_ = read_data;
217 if (op.
type == ReadOperation::OperationType::BLOCK)
219 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
221 return ErrorCode::OK;
226 HAL_I2C_Mem_Read(i2c_handle_, dev_addr, mem_addr,
227 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
228 : I2C_MEMADD_SIZE_16BIT,
229 reinterpret_cast<uint8_t*
>(read_data.
addr_), read_data.
size_,
235 if (op.
type == ReadOperation::OperationType::BLOCK)
237 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
245 MemAddrLength mem_addr_size,
bool in_isr)
249 if (i2c_handle_->State != HAL_I2C_STATE_READY)
251 return ErrorCode::BUSY;
256 const uint16_t dev_addr = EncodeHalDevAddress(i2c_handle_, slave_addr);
260 if (write_data.
size_ > dma_enable_min_size_)
263#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
264 SCB_CleanDCache_by_Addr(
reinterpret_cast<uint32_t*
>(dma_buff_.
addr_),
267 HAL_I2C_Mem_Write_DMA(i2c_handle_, dev_addr, mem_addr,
268 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
269 : I2C_MEMADD_SIZE_16BIT,
270 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_), write_data.
size_);
272 if (op.
type == WriteOperation::OperationType::BLOCK)
274 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
276 return ErrorCode::OK;
281 HAL_I2C_Mem_Write(i2c_handle_, dev_addr, mem_addr,
282 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
283 : I2C_MEMADD_SIZE_16BIT,
284 reinterpret_cast<uint8_t*
>(dma_buff_.
addr_), write_data.
size_,
290 if (op.
type == WriteOperation::OperationType::BLOCK)
292 return op.
data.sem_info.sem->
Wait(op.
data.sem_info.timeout);
302 SetClockSpeed<decltype(i2c_handle_)>(i2c_handle_, config);
306 return ErrorCode::NOT_SUPPORT;
309 if (HAL_I2C_Init(i2c_handle_) != HAL_OK)
311 return ErrorCode::INIT_ERR;
313 return ErrorCode::OK;
316extern "C" void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef* hi2c)
318 STM32I2C* i2c = STM32I2C::map[STM32_I2C_GetID(hi2c->Instance)];
321#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
322 SCB_InvalidateDCache_by_Addr(i2c->dma_buff_.
addr_, i2c->read_buff_.
size_);
329extern "C" void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef* hi2c)
331 STM32I2C* i2c = STM32I2C::map[STM32_I2C_GetID(hi2c->Instance)];
338extern "C" void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef* hi2c)
340 STM32I2C* i2c = STM32I2C::map[STM32_I2C_GetID(hi2c->Instance)];
347extern "C" void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef* hi2c)
349 STM32I2C* i2c = STM32I2C::map[STM32_I2C_GetID(hi2c->Instance)];
352#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
353 SCB_InvalidateDCache_by_Addr(i2c->dma_buff_.
addr_, i2c->read_buff_.
size_);
360extern "C" void HAL_I2C_ErrorCallback(I2C_HandleTypeDef* hi2c)
362 STM32I2C* i2c = STM32I2C::map[STM32_I2C_GetID(hi2c->Instance)];
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
I2C(Inter-Integrated Circuit)接口类。 I2C (Inter-Integrated Circuit) interface class.
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
union LibXR::Operation::@5 data
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
STM32 I2C 驱动实现 / STM32 I2C driver implementation.
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, 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.
ErrorCode Write(uint16_t slave_addr, ConstRawData write_data, WriteOperation &op, bool in_isr) override
向 I2C 设备写入数据。 Writes data to an I2C device.
ErrorCode Read(uint16_t slave_addr, RawData read_data, ReadOperation &op, bool in_isr) override
读取 I2C 设备的数据。 Reads data from an I2C device.
STM32I2C(I2C_HandleTypeDef *hi2c, RawData dma_buff, uint32_t dma_enable_min_size=3)
构造 I2C 对象 / Construct I2C object
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
I2C 设备的配置信息结构体。 Configuration structure for an I2C device.