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