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 * 2024-01-20 wirano first version
9 */
10
11
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 #include <rtdbg.h>
15
16 #ifdef BSP_USING_I2C
17
18 #if defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3)
19
20 #include "drv_i2c.h"
21 #include "inc/hw_memmap.h"
22 #include "i2c_config.h"
23
24 enum {
25 #ifdef BSP_USING_I2C0
26 I2C0_INDEX,
27 #endif
28 #ifdef BSP_USING_I2C1
29 I2C1_INDEX,
30 #endif
31 #ifdef BSP_USING_I2C2
32 I2C2_INDEX,
33 #endif
34 #ifdef BSP_USING_I2C3
35 I2C3_INDEX,
36 #endif
37 };
38
39 static struct tm4c123_i2c tm4c123_i2cs[] =
40 {
41 #ifdef BSP_USING_I2C0
42 I2C0_BUS_CONFIG,
43 #endif
44
45 #ifdef BSP_USING_I2C1
46 I2C1_BUS_CONFIG,
47 #endif
48
49 #ifdef BSP_USING_I2C2
50 I2C2_BUS_CONFIG,
51 #endif
52
53 #ifdef BSP_USING_I2C3
54 I2C3_BUS_CONFIG,
55 #endif
56 };
57
58
59 static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
60
61
62 struct rt_i2c_bus_device_ops tm4c123_i2c_ops =
63 {
64 tm4c123_i2c_xfer,
65 RT_NULL,
66 RT_NULL
67 };
68
69
tm4c123_i2c_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)70 static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) {
71 RT_ASSERT(bus != RT_NULL);
72 RT_ASSERT(msgs != RT_NULL);
73
74 struct rt_i2c_msg *msg;
75 struct tm4c123_i2c *i2c_info = (struct tm4c123_i2c *) bus;
76
77 rt_err_t ret = -RT_ERROR;
78 rt_uint32_t i;
79
80 for (i = 0; i < num; i++) {
81 msg = &msgs[i];
82
83 if (msg->flags & RT_I2C_ADDR_10BIT) {
84 LOG_E("does not support 10bits address!\n");
85 }
86
87 if (msg->flags & RT_I2C_RD) {
88 rt_uint8_t *data = msg->buf;
89
90 ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, true);
91
92 if (msg->flags & RT_I2C_NO_START) {
93 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
94 while (ROM_I2CMasterBusy(i2c_info->base));
95 *data = ROM_I2CMasterDataGet(i2c_info->base);
96 } else {
97 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_START);
98 while (ROM_I2CMasterBusy(i2c_info->base));
99 *data = ROM_I2CMasterDataGet(i2c_info->base);
100 }
101
102 if (msg->len > 1) {
103 data++;
104
105 for (int j = 1; j < msg->len - 1; ++j) {
106
107 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
108 while (ROM_I2CMasterBusy(i2c_info->base));
109 *data = ROM_I2CMasterDataGet(i2c_info->base);
110 data++;
111 }
112
113 if (msg->flags & RT_I2C_NO_STOP) {
114 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
115 while (ROM_I2CMasterBusy(i2c_info->base));
116 *data = ROM_I2CMasterDataGet(i2c_info->base);
117 } else {
118 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
119 while (ROM_I2CMasterBusy(i2c_info->base));
120 *data = ROM_I2CMasterDataGet(i2c_info->base);
121 }
122 }
123 } else {
124 rt_uint8_t *data = msg->buf;
125
126 ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, false);
127
128 // use single send when data len = 1
129 if (msg->len == 1) {
130 if (msg->flags & RT_I2C_NO_START) {
131 ROM_I2CMasterDataPut(i2c_info->base, *data);
132 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
133 } else if (msg->flags & RT_I2C_NO_STOP) {
134 ROM_I2CMasterDataPut(i2c_info->base, *data);
135 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
136 } else {
137 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_SINGLE_SEND);
138 ROM_I2CMasterDataPut(i2c_info->base, *data);
139 }
140 while (ROM_I2CMasterBusy(i2c_info->base));
141 // otherwise use burst send
142 } else {
143 if (msg->flags & RT_I2C_NO_START) {
144 ROM_I2CMasterDataPut(i2c_info->base, *data);
145 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
146 while (ROM_I2CMasterBusy(i2c_info->base));
147 } else {
148 ROM_I2CMasterDataPut(i2c_info->base, *data);
149 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_START);
150 while (ROM_I2CMasterBusy(i2c_info->base));
151 }
152
153 data++;
154
155 for (int j = 1; j < msg->len - 1; ++j) {
156 ROM_I2CMasterDataPut(i2c_info->base, *data);
157 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
158 while (ROM_I2CMasterBusy(i2c_info->base));
159 data++;
160 }
161
162 if (msg->flags & RT_I2C_NO_STOP) {
163 ROM_I2CMasterDataPut(i2c_info->base, *data);
164 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
165 } else {
166 ROM_I2CMasterDataPut(i2c_info->base, *data);
167 ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_FINISH);
168 }
169 while (ROM_I2CMasterBusy(i2c_info->base));
170 }
171
172 }
173 }
174 ret = i;
175 return ret;
176 }
177
rt_hw_i2c_init(void)178 int rt_hw_i2c_init(void) {
179 rt_err_t ret = RT_EOK;
180
181 i2c_hw_config();
182
183 for (uint32_t i = 0; i < sizeof(tm4c123_i2cs) / sizeof(tm4c123_i2cs[0]); i++) {
184 if (tm4c123_i2cs[i].clk_freq == 400000) {
185 ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_TRUE);
186 } else {
187 ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_FALSE);
188 }
189 ROM_I2CMasterEnable(tm4c123_i2cs[i].base);
190
191 tm4c123_i2cs[i].bus.ops = &tm4c123_i2c_ops;
192 ret = rt_i2c_bus_device_register(&tm4c123_i2cs[i].bus, tm4c123_i2cs[i].bus_name);
193 if (ret != RT_EOK) {
194 LOG_E("rt i2c device %s register failed, status=%d\n", tm4c123_i2cs[i].bus_name, ret);
195 }
196 }
197
198 return ret;
199 }
200
201 INIT_DEVICE_EXPORT(rt_hw_i2c_init);
202
203 #endif /* BSP_USING_I2C1 || BSP_USING_I2C2 || BSP_USING_I2C3 || BSP_USING_I2C4 */
204
205 #endif /* BSP_USING_I2C */
206
207