1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-02-22 airm2m first version
9 */
10
11 #include <rtdevice.h>
12 #include <rtthread.h>
13 #include "board.h"
14 #ifdef BSP_USING_I2C
15
16 static struct rt_i2c_bus_device prv_air105_i2c;
17 static rt_ssize_t air105_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
18 struct rt_i2c_msg msgs[],
19 rt_uint32_t num);
20 static rt_ssize_t air105_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
21 struct rt_i2c_msg msgs[],
22 rt_uint32_t num);
23 static rt_err_t air105_i2c_bus_control(struct rt_i2c_bus_device *bus,
24 int cmd,
25 void *args);
26
27 static const struct rt_i2c_bus_device_ops air105_i2c_ops =
28 {
29 .master_xfer = air105_i2c_mst_xfer,
30 .slave_xfer = RT_NULL,
31 .i2c_bus_control = air105_i2c_bus_control
32 };
33
34
air105_i2c_mst_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)35 static rt_ssize_t air105_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
36 struct rt_i2c_msg msgs[],
37 rt_uint32_t num)
38 {
39 rt_size_t i;
40 uint64_t tick;
41 struct rt_i2c_msg *msg = msgs;
42 RT_ASSERT(bus != RT_NULL);
43 rt_uint32_t i2c_id = (rt_uint32_t)bus->priv;
44 rt_int32_t Result;
45 while(!I2C_WaitResult(i2c_id, &Result)) {;}
46 for (i = 0; i < num; i++)
47 {
48 if (!(msg[i].flags & RT_I2C_NO_START))
49 {
50 if (msg[i].flags & RT_I2C_ADDR_10BIT)
51 {
52 I2C_Prepare(i2c_id, msg[i].addr, 2, NULL, NULL);
53 }
54 else
55 {
56 I2C_Prepare(i2c_id, msg[i].addr, 1, NULL, NULL);
57 }
58 }
59 if (msg[i].flags & RT_I2C_RD)
60 {
61 tick = GetSysTick();
62 I2C_MasterXfer(i2c_id, I2C_OP_READ, 0, msg[i].buf, msg[i].len, bus->timeout);
63 while(!I2C_WaitResult(i2c_id, &Result) && !SysTickCheckTimeout(tick, bus->timeout * CORE_TICK_1MS)){;}
64 if (!I2C_WaitResult(i2c_id, &Result))
65 {
66 I2C_ForceStop(i2c_id);
67 return -RT_EIO;
68 }
69 }
70 else
71 {
72 tick = GetSysTick();
73 I2C_MasterXfer(i2c_id, I2C_OP_WRITE, 0, msg[i].buf, msg[i].len, bus->timeout);
74 while(!I2C_WaitResult(i2c_id, &Result) && !SysTickCheckTimeout(tick, bus->timeout * CORE_TICK_1MS)){;}
75 if (!I2C_WaitResult(i2c_id, &Result))
76 {
77 I2C_ForceStop(i2c_id);
78 return -RT_EIO;
79 }
80 }
81 }
82 return i;
83 }
air105_i2c_slv_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)84 static rt_ssize_t air105_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
85 struct rt_i2c_msg msgs[],
86 rt_uint32_t num)
87 {
88 return -RT_ENOSYS;
89 }
air105_i2c_bus_control(struct rt_i2c_bus_device * bus,int cmd,void * args)90 static rt_err_t air105_i2c_bus_control(struct rt_i2c_bus_device *bus,
91 int cmd,
92 void *args)
93 {
94
95 RT_ASSERT(bus != RT_NULL);
96 rt_uint32_t i2c_id = (rt_uint32_t)bus->priv;
97 switch (cmd)
98 {
99 case RT_I2C_DEV_CTRL_CLK:
100 I2C_MasterSetup(i2c_id, *(rt_uint32_t *)args);
101 break;
102 default:
103 return -RT_EIO;
104 }
105
106 return RT_EOK;
107 }
108
air105_hw_i2c_init(void)109 int air105_hw_i2c_init(void)
110 {
111 I2C_GlobalInit();
112 prv_air105_i2c.ops = &air105_i2c_ops;
113 prv_air105_i2c.priv = 0;
114 I2C_MasterSetup(0, 400000);
115 GPIO_Iomux(GPIOE_06, 2);
116 GPIO_Iomux(GPIOE_07, 2);
117 #ifdef I2C_BUS_NAME
118 rt_i2c_bus_device_register(&prv_air105_i2c, I2C_BUS_NAME);
119 #else
120 rt_i2c_bus_device_register(&prv_air105_i2c, "i2c");
121 #endif
122
123 return 0;
124 }
125 INIT_DEVICE_EXPORT(air105_hw_i2c_init);
126
127 #endif /* BSP_USING_I2C */
128