1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2012-04-25 weety first version
9 * 2021-04-20 RiceChen added support for bus control api
10 */
11
12 #ifndef __DEV_I2C_H__
13 #define __DEV_I2C_H__
14
15 #include <rtthread.h>
16 /**
17 * @defgroup group_drivers_i2c I2C
18 * @brief I2C driver api
19 * @ingroup group_device_driver
20 *
21 * <b>Example</b>
22 * @code {.c}
23 * #include <rtthread.h>
24 * #include <rtdevice.h>
25 *
26 * #define AHT10_I2C_BUS_NAME "i2c1" // 传感器连接的I2C总线设备名称
27 * #define AHT10_ADDR 0x38 // 从机地址
28 * #define AHT10_CALIBRATION_CMD 0xE1 // 校准命令
29 * #define AHT10_NORMAL_CMD 0xA8 // 一般命令
30 * #define AHT10_GET_DATA 0xAC // 获取数据命令
31 *
32 * static struct rt_i2c_bus_device *i2c_bus = RT_NULL; // I2C总线设备句柄
33 * static rt_bool_t initialized = RT_FALSE; // 传感器初始化状态
34 *
35 * // 写传感器寄存器
36 * static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data)
37 * {
38 * rt_uint8_t buf[3];
39 * struct rt_i2c_msg msgs;
40 * rt_uint32_t buf_size = 1;
41 *
42 * buf[0] = reg; //cmd
43 * if (data != RT_NULL)
44 * {
45 * buf[1] = data[0];
46 * buf[2] = data[1];
47 * buf_size = 3;
48 * }
49 *
50 * msgs.addr = AHT10_ADDR;
51 * msgs.flags = RT_I2C_WR;
52 * msgs.buf = buf;
53 * msgs.len = buf_size;
54 *
55 * // 调用I2C设备接口传输数据
56 * if (rt_i2c_transfer(bus, &msgs, 1) == 1)
57 * {
58 * return RT_EOK;
59 * }
60 * else
61 * {
62 * return -RT_ERROR;
63 * }
64 * }
65 *
66 * // 读传感器寄存器数据
67 * static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
68 * {
69 * struct rt_i2c_msg msgs;
70 *
71 * msgs.addr = AHT10_ADDR;
72 * msgs.flags = RT_I2C_RD;
73 * msgs.buf = buf;
74 * msgs.len = len;
75 *
76 * // 调用I2C设备接口传输数据
77 * if (rt_i2c_transfer(bus, &msgs, 1) == 1)
78 * {
79 * return RT_EOK;
80 * }
81 * else
82 * {
83 * return -RT_ERROR;
84 * }
85 * }
86 *
87 * static void read_temp_humi(float *cur_temp, float *cur_humi)
88 * {
89 * rt_uint8_t temp[6];
90 *
91 * write_reg(i2c_bus, AHT10_GET_DATA, RT_NULL); // 发送命令
92 * rt_thread_mdelay(400);
93 * read_regs(i2c_bus, 6, temp); // 获取传感器数据
94 *
95 * // 湿度数据转换
96 * *cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20);
97 * // 温度数据转换
98 * *cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
99 * }
100 *
101 * static void aht10_init(const char *name)
102 * {
103 * rt_uint8_t temp[2] = {0, 0};
104 *
105 * // 查找I2C总线设备,获取I2C总线设备句柄
106 * i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
107 *
108 * if (i2c_bus == RT_NULL)
109 * {
110 * rt_kprintf("can't find %s device!\n", name);
111 * }
112 * else
113 * {
114 * write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);
115 * rt_thread_mdelay(400);
116 *
117 * temp[0] = 0x08;
118 * temp[1] = 0x00;
119 * write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);
120 * rt_thread_mdelay(400);
121 * initialized = RT_TRUE;
122 * }
123 * }
124 *
125 * static void i2c_aht10_sample(int argc, char *argv[])
126 * {
127 * float humidity, temperature;
128 * char name[RT_NAME_MAX];
129 *
130 * humidity = 0.0;
131 * temperature = 0.0;
132 *
133 * if (argc == 2)
134 * {
135 * rt_strncpy(name, argv[1], RT_NAME_MAX);
136 * }
137 * else
138 * {
139 * rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX);
140 * }
141 *
142 * if (!initialized)
143 * {
144 * // 传感器初始化
145 * aht10_init(name);
146 * }
147 * if (initialized)
148 * {
149 * // 读取温湿度数据
150 * read_temp_humi(&temperature, &humidity);
151 *
152 * rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10);
153 * if( temperature >= 0 )
154 * {
155 * rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(temperature * 10) % 10);
156 * }
157 * else
158 * {
159 * rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(-temperature * 10) % 10);
160 * }
161 * }
162 * else
163 * {
164 * rt_kprintf("initialize sensor failed!\n");
165 * }
166 * }
167 * // 导出到 msh 命令列表中
168 * MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample);
169 * @endcode
170 */
171
172 /*!
173 * @addtogroup group_drivers_i2c
174 * @{
175 */
176 #ifdef __cplusplus
177 extern "C" {
178 #endif
179
180 #define RT_I2C_WR 0x0000 /*!< i2c wirte flag */
181 #define RT_I2C_RD (1u << 0) /*!< i2c read flag */
182 #define RT_I2C_ADDR_10BIT (1u << 2) /*!< this is a ten bit chip address */
183 #define RT_I2C_NO_START (1u << 4) /*!< do not generate START condition */
184 #define RT_I2C_IGNORE_NACK (1u << 5) /*!< ignore NACK from slave */
185 #define RT_I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */
186 #define RT_I2C_NO_STOP (1u << 7) /*!< do not generate STOP condition */
187
188 #define RT_I2C_DEV_CTRL_10BIT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x01)
189 #define RT_I2C_DEV_CTRL_ADDR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x02)
190 #define RT_I2C_DEV_CTRL_TIMEOUT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x03)
191 #define RT_I2C_DEV_CTRL_RW (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x04)
192 #define RT_I2C_DEV_CTRL_CLK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x05)
193 #define RT_I2C_DEV_CTRL_UNLOCK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x06)
194 #define RT_I2C_DEV_CTRL_GET_STATE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x07)
195 #define RT_I2C_DEV_CTRL_GET_MODE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x08)
196 #define RT_I2C_DEV_CTRL_GET_ERROR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x09)
197
198 /**
199 * @brief I2C Private Data
200 */
201 struct rt_i2c_priv_data
202 {
203 struct rt_i2c_msg *msgs;
204 rt_size_t number;
205 };
206
207 /**
208 * @brief I2C Message
209 */
210 struct rt_i2c_msg
211 {
212 rt_uint16_t addr;
213 rt_uint16_t flags;
214 rt_uint16_t len;
215 rt_uint8_t *buf;
216 };
217
218 struct rt_i2c_bus_device;
219
220 /**
221 * @brief I2C Bus Device Operations
222 */
223 struct rt_i2c_bus_device_ops
224 {
225 rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus,
226 struct rt_i2c_msg msgs[],
227 rt_uint32_t num);
228 rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus,
229 struct rt_i2c_msg msgs[],
230 rt_uint32_t num);
231 rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus,
232 int cmd,
233 void *args);
234 };
235
236 /**
237 * @brief I2C Bus Device
238 */
239 struct rt_i2c_bus_device
240 {
241 struct rt_device parent;
242 const struct rt_i2c_bus_device_ops *ops;
243 rt_uint16_t flags;
244 struct rt_mutex lock;
245 rt_uint32_t timeout;
246 rt_uint32_t retries;
247 void *priv;
248 };
249
250 /**
251 * @brief I2C Client
252 */
253 struct rt_i2c_client
254 {
255 #ifdef RT_USING_DM
256 struct rt_device parent;
257
258 const char *name;
259 const struct rt_i2c_device_id *id;
260 const struct rt_ofw_node_id *ofw_id;
261 #endif
262 struct rt_i2c_bus_device *bus;
263 rt_uint16_t client_addr;
264 };
265
266 #ifdef RT_USING_DM
267 struct rt_i2c_device_id
268 {
269 char name[20];
270 void *data;
271 };
272
273 struct rt_i2c_driver
274 {
275 struct rt_driver parent;
276
277 const struct rt_i2c_device_id *ids;
278 const struct rt_ofw_node_id *ofw_ids;
279
280 rt_err_t (*probe)(struct rt_i2c_client *client);
281 rt_err_t (*remove)(struct rt_i2c_client *client);
282 rt_err_t (*shutdown)(struct rt_i2c_client *client);
283 };
284
285 rt_err_t rt_i2c_driver_register(struct rt_i2c_driver *driver);
286 rt_err_t rt_i2c_device_register(struct rt_i2c_client *client);
287
288 #define RT_I2C_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, i2c, BUILIN)
289 #endif /* RT_USING_DM */
290
291 /**
292 * @brief I2C Bus Device Initialization
293 *
294 * @param bus the I2C bus device
295 * @param name the name of I2C bus device
296 *
297 * @return rt_err_t error code
298 */
299 rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
300 const char *name);
301
302 /**
303 * @brief I2C Bus Device Register
304 *
305 * @param bus the I2C bus device
306 * @param bus_name the name of I2C bus device
307 *
308 * @return rt_err_t error code
309 */
310 rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
311 const char *bus_name);
312
313 /**
314 * @brief I2C Bus Device Find
315 *
316 * @param bus_name the name of I2C bus device
317 *
318 * @return rt_i2c_bus_device the I2C bus device
319 */
320 struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name);
321
322 /**
323 * @brief I2C data transmission.
324 *
325 * @param bus the I2C bus device
326 * @param msgs the I2C message list
327 * @param num the number of I2C message
328 *
329 * @return rt_ssize_t the actual length of transmitted
330 */
331 rt_ssize_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
332 struct rt_i2c_msg msgs[],
333 rt_uint32_t num);
334
335 /**
336 * @brief I2C Control
337 *
338 * @param bus the I2C bus device
339 * @param cmd the I2C control command
340 * @param args the I2C control arguments
341 *
342 * @return rt_err_t error code
343 */
344 rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
345 int cmd,
346 void *args);
347
348 /**
349 * @brief I2C Master Send
350 *
351 * @param bus the I2C bus device
352 * @param addr the I2C slave address
353 * @param flags the I2C flags
354 * @param buf the I2C send buffer
355 * @param count the I2C send buffer length
356 *
357 * @return rt_ssize_t the actual length of transmitted
358 */
359 rt_ssize_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
360 rt_uint16_t addr,
361 rt_uint16_t flags,
362 const rt_uint8_t *buf,
363 rt_uint32_t count);
364
365 /**
366 * @brief I2C Master Receive
367 *
368 * @param bus the I2C bus device
369 * @param addr the I2C slave address
370 * @param flags the I2C flags
371 * @param buf the I2C receive buffer
372 * @param count the I2C receive buffer length
373 *
374 * @return rt_ssize_t the actual length of received
375 */
376 rt_ssize_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
377 rt_uint16_t addr,
378 rt_uint16_t flags,
379 rt_uint8_t *buf,
380 rt_uint32_t count);
381
rt_i2c_bus_lock(struct rt_i2c_bus_device * bus,rt_tick_t timeout)382 rt_inline rt_err_t rt_i2c_bus_lock(struct rt_i2c_bus_device *bus, rt_tick_t timeout)
383 {
384 return rt_mutex_take(&bus->lock, timeout);
385 }
386
rt_i2c_bus_unlock(struct rt_i2c_bus_device * bus)387 rt_inline rt_err_t rt_i2c_bus_unlock(struct rt_i2c_bus_device *bus)
388 {
389 return rt_mutex_release(&bus->lock);
390 }
391
392 #ifdef __cplusplus
393 }
394 #endif
395
396 /*! @}*/
397
398 #endif
399