libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_i2c.hpp
1#pragma once
2
3#include "main.h"
4
5#ifdef HAL_I2C_MODULE_ENABLED
6
7#ifdef I2C
8#undef I2C
9#endif
10
11#include "i2c.hpp"
12#include "libxr.hpp"
13
14typedef enum
15{
16#ifdef I2C1
17 STM32_I2C1,
18#endif
19#ifdef I2C2
20 STM32_I2C2,
21#endif
22#ifdef I2C3
23 STM32_I2C3,
24#endif
25#ifdef I2C4
26 STM32_I2C4,
27#endif
28#ifdef I2C5
29 STM32_I2C5,
30#endif
31#ifdef I2C6
32 STM32_I2C6,
33#endif
34#ifdef I2C7
35 STM32_I2C7,
36#endif
37#ifdef I2C8
38 STM32_I2C8,
39#endif
40 STM32_I2C_NUMBER,
41 STM32_I2C_ID_ERROR
42} stm32_i2c_id_t;
43
44stm32_i2c_id_t STM32_I2C_GetID(I2C_TypeDef *hi2c); // NOLINT
45
46namespace LibXR
47{
48class STM32I2C : public I2C
49{
50 public:
52 : I2C(),
53 id_(STM32_I2C_GetID(hi2c->Instance)),
54 i2c_handle_(hi2c),
55 dma_enable_min_size_(dma_enable_min_size),
56 dma_buff_(dma_buff)
57 {
58 map[id_] = this;
59 }
60
61 ErrorCode Read(uint16_t slave_addr, RawData read_data, ReadOperation &op) override
62 {
63 if (i2c_handle_->State != HAL_I2C_STATE_READY)
64 {
65 return ErrorCode::BUSY;
66 }
67
68 read_ = true;
69
70 if (read_data.size_ > dma_enable_min_size_)
71 {
72 read_op_ = op;
74 reinterpret_cast<uint8_t *>(dma_buff_.addr_),
75 read_data.size_);
76 read_buff_ = read_data;
77 op.MarkAsRunning();
78 if (op.type == ReadOperation::OperationType::BLOCK)
79 {
80 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
81 }
82 return ErrorCode::OK;
83 }
84 else
85 {
86 auto ans = HAL_I2C_Master_Receive(i2c_handle_, slave_addr,
87 reinterpret_cast<uint8_t *>(read_data.addr_),
88 read_data.size_, 20) == HAL_OK
89 ? ErrorCode::OK
90 : ErrorCode::BUSY;
91 op.UpdateStatus(false, std::forward<ErrorCode>(ans));
92 if (op.type == ReadOperation::OperationType::BLOCK)
93 {
94 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
95 }
96 return ans;
97 }
98 }
99
100 ErrorCode Write(uint16_t slave_addr, ConstRawData write_data,
101 WriteOperation &op) override
102 {
103 if (i2c_handle_->State != HAL_I2C_STATE_READY)
104 {
105 return ErrorCode::BUSY;
106 }
107
108 read_ = false;
109
110 memcpy(dma_buff_.addr_, write_data.addr_, write_data.size_);
111
112 if (write_data.size_ > dma_enable_min_size_)
113 {
114 write_op_ = op;
116 reinterpret_cast<uint8_t *>(dma_buff_.addr_),
117 write_data.size_);
118 op.MarkAsRunning();
119 if (op.type == WriteOperation::OperationType::BLOCK)
120 {
121 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
122 }
123 return ErrorCode::OK;
124 }
125 else
126 {
127 auto ans = HAL_I2C_Master_Transmit(i2c_handle_, slave_addr,
128 reinterpret_cast<uint8_t *>(dma_buff_.addr_),
129 write_data.size_, 20) == HAL_OK
130 ? ErrorCode::OK
131 : ErrorCode::BUSY;
132 op.UpdateStatus(false, std::forward<ErrorCode>(ans));
133 if (op.type == WriteOperation::OperationType::BLOCK)
134 {
135 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
136 }
137 return ans;
138 }
139 }
140
142 ReadOperation &op, MemAddrLength mem_addr_size) override
143 {
144 ASSERT(read_data.size_ <= dma_buff_.size_);
145
146 if (i2c_handle_->State != HAL_I2C_STATE_READY)
147 {
148 return ErrorCode::BUSY;
149 }
150
151 read_ = true;
152
153 if (read_data.size_ > dma_enable_min_size_)
154 {
155 read_op_ = op;
157 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
159 reinterpret_cast<uint8_t *>(dma_buff_.addr_), read_data.size_);
160 read_buff_ = read_data;
161 op.MarkAsRunning();
162 if (op.type == ReadOperation::OperationType::BLOCK)
163 {
164 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
165 }
166 return ErrorCode::OK;
167 }
168 else
169 {
170 auto ans =
172 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
174 reinterpret_cast<uint8_t *>(read_data.addr_), read_data.size_,
175 20) == HAL_OK
176 ? ErrorCode::OK
177 : ErrorCode::BUSY;
178
179 op.UpdateStatus(false, std::forward<ErrorCode>(ans));
180 if (op.type == ReadOperation::OperationType::BLOCK)
181 {
182 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
183 }
184 return ans;
185 }
186 }
187
189 WriteOperation &op, MemAddrLength mem_addr_size) override
190 {
191 ASSERT(write_data.size_ <= dma_buff_.size_);
192
193 if (i2c_handle_->State != HAL_I2C_STATE_READY)
194 {
195 return ErrorCode::BUSY;
196 }
197
198 read_ = false;
199
200 memcpy(dma_buff_.addr_, write_data.addr_, write_data.size_);
201
202 if (write_data.size_ > dma_enable_min_size_)
203 {
204 write_op_ = op;
206 i2c_handle_, slave_addr, mem_addr,
207 mem_addr_size == MemAddrLength::BYTE_8 ? I2C_MEMADD_SIZE_8BIT
209 reinterpret_cast<uint8_t *>(dma_buff_.addr_), write_data.size_);
210 op.MarkAsRunning();
211 if (op.type == WriteOperation::OperationType::BLOCK)
212 {
213 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
214 }
215 return ErrorCode::OK;
216 }
217 else
218 {
219 auto ans = HAL_I2C_Mem_Write(i2c_handle_, slave_addr, mem_addr,
220 mem_addr_size == MemAddrLength::BYTE_8
223 reinterpret_cast<uint8_t *>(dma_buff_.addr_),
224 write_data.size_, 20) == HAL_OK
225 ? ErrorCode::OK
226 : ErrorCode::BUSY;
227
228 op.UpdateStatus(false, std::forward<ErrorCode>(ans));
229 if (op.type == WriteOperation::OperationType::BLOCK)
230 {
231 return op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
232 }
233 return ans;
234 }
235 }
236
237 template <typename, typename = void>
238 struct HasClockSpeed : std::false_type
239 {
240 };
241
242 template <typename T>
243 struct HasClockSpeed<T, std::void_t<decltype(std::declval<T>()->Init.ClockSpeed)>>
244 : std::true_type
245 {
246 };
247
248 template <typename T>
249 typename std::enable_if<!HasClockSpeed<T>::value>::type SetClockSpeed(
250 T &, const Configuration &)
251 {
252 }
253
254 template <typename T>
255 typename std::enable_if<HasClockSpeed<T>::value>::type SetClockSpeed(
256 T &i2c_handle, const Configuration &config)
257 {
258 i2c_handle->Init.ClockSpeed = config.clock_speed;
259 }
260
261 ErrorCode SetConfig(Configuration config) override
262 {
263 if (HasClockSpeed<decltype(i2c_handle_)>::value)
264 {
266 }
267 else
268 {
269 return ErrorCode::NOT_SUPPORT;
270 }
271
272 if (HAL_I2C_Init(i2c_handle_) != HAL_OK)
273 {
274 return ErrorCode::INIT_ERR;
275 }
276 return ErrorCode::OK;
277 }
278
279 stm32_i2c_id_t id_;
280 I2C_HandleTypeDef *i2c_handle_;
281 uint32_t dma_enable_min_size_;
282
283 RawData dma_buff_;
284
285 ReadOperation read_op_;
286 WriteOperation write_op_;
287 RawData read_buff_;
288
289 bool read_ = false;
290
291 static STM32I2C *map[STM32_I2C_NUMBER]; // NOLINT
292};
293} // namespace LibXR
294
295#endif
常量原始数据封装类。 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.
Definition i2c.hpp:17
I2C()
默认构造函数。 Default constructor.
Definition i2c.hpp:39
void UpdateStatus(bool in_isr, Args &&...args)
Updates operation status based on type.
Definition libxr_rw.hpp:207
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Definition libxr_rw.hpp:238
union LibXR::Operation::@4 data
OperationType type
Definition libxr_rw.hpp:261
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
ErrorCode MemWrite(uint16_t slave_addr, uint16_t mem_addr, ConstRawData write_data, WriteOperation &op, MemAddrLength mem_addr_size) override
向 I2C 设备指定寄存器写入数据。 Writes data to a specific register of 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) override
从 I2C 设备指定寄存器读取数据。 Reads data from a specific register of an I2C device.
ErrorCode Write(uint16_t slave_addr, ConstRawData write_data, WriteOperation &op) override
向 I2C 设备写入数据。 Writes data to an I2C device.
ErrorCode Read(uint16_t slave_addr, RawData read_data, ReadOperation &op) override
读取 I2C 设备的数据。 Reads data from an I2C device.
Definition stm32_i2c.hpp:61
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
Definition semaphore.cpp:15
LibXR Color Control Library / LibXR终端颜色控制库
Definition esp_gpio.hpp:8
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
I2C 设备的配置信息结构体。 Configuration structure for an I2C device.
Definition i2c.hpp:24