1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2017-12-04 Haley the first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "am_mcu_apollo.h"
14
15 /* I2C0 */
16 #define AM_I2C0_IOM_INST 0
17
18 #define I2C0_GPIO_SCL 5
19 #define I2C0_GPIO_CFG_SCK AM_HAL_PIN_5_M0SCL
20 #define I2C0_GPIO_SDA 6
21 #define I2C0_GPIO_CFG_SDA AM_HAL_PIN_6_M0SDA
22
23 /* I2C2 */
24 #define AM_I2C2_IOM_INST 2
25
26 #define I2C2_GPIO_SCL 27
27 #define I2C2_GPIO_CFG_SCK AM_HAL_PIN_27_M2SCL
28 #define I2C2_GPIO_SDA 25
29 #define I2C2_GPIO_CFG_SDA AM_HAL_PIN_25_M2SDA
30
31 /* I2C3 */
32 #define AM_I2C3_IOM_INST 3
33
34 #define I2C3_GPIO_SCL 42
35 #define I2C3_GPIO_CFG_SCK AM_HAL_PIN_42_M3SCL
36 #define I2C3_GPIO_SDA 43
37 #define I2C3_GPIO_CFG_SDA AM_HAL_PIN_43_M3SDA
38
39 /* I2C4 */
40 #define AM_I2C4_IOM_INST 4
41
42 #define I2C4_GPIO_SCL 39
43 #define I2C4_GPIO_CFG_SCK AM_HAL_PIN_39_M4SCL
44 #define I2C4_GPIO_SDA 40
45 #define I2C4_GPIO_CFG_SDA AM_HAL_PIN_40_M4SDA
46
47 static am_hal_iom_config_t g_sIOMConfig =
48 {
49 AM_HAL_IOM_I2CMODE, // ui32InterfaceMode
50 AM_HAL_IOM_100KHZ, // ui32ClockFrequency
51 0, // bSPHA
52 0, // bSPOL
53 4, // ui8WriteThreshold
54 60, // ui8ReadThreshold
55 };
56
57 /* AM i2c driver */
58 struct am_i2c_bus
59 {
60 struct rt_i2c_bus_device parent;
61 rt_uint32_t u32Module;
62 };
63
64 //connect am drv to rt drv.
rt_i2c_master_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg * msgs,rt_uint32_t num)65 rt_size_t rt_i2c_master_xfer(struct rt_i2c_bus_device *bus,
66 struct rt_i2c_msg *msgs,
67 rt_uint32_t num)
68 {
69 struct am_i2c_bus * am_i2c_bus = (struct am_i2c_bus *)bus;
70 struct rt_i2c_msg *msg;
71 int i;
72 rt_uint32_t msg_len = 0;
73
74 for (i = 0; i < num; i++)
75 {
76 msg = &msgs[i];
77 if (msg->flags == RT_I2C_RD)
78 {
79 am_hal_iom_i2c_read(am_i2c_bus->u32Module, msg->addr, (uint32_t *)msg->buf, msg->len, AM_HAL_IOM_RAW);
80 msg_len += msg->len;
81 }
82 else if(msg->flags == RT_I2C_WR)
83 {
84 am_hal_iom_i2c_write(am_i2c_bus->u32Module, msg->addr, (uint32_t *)msg->buf, msg->len, AM_HAL_IOM_RAW);
85 msg_len += (msg->len - 1);
86 }
87 }
88
89 return msg_len;
90 }
91
rt_i2c_bus_control(struct rt_i2c_bus_device * bus,int cmd,void * args)92 rt_err_t rt_i2c_bus_control(struct rt_i2c_bus_device *bus,
93 int cmd,
94 void *args)
95 {
96 struct am_i2c_bus * am_i2c_bus = (struct am_i2c_bus *)bus;
97 //rt_uint32_t ctrl_arg = *(rt_uint32_t *)args;
98
99 RT_ASSERT(bus != RT_NULL);
100 am_i2c_bus = (struct am_i2c_bus *)bus->parent.user_data;
101
102 RT_ASSERT(am_i2c_bus != RT_NULL);
103
104 switch (cmd)
105 {
106 /* I2C config */
107 case RT_DEVICE_CTRL_CONFIG :
108 break;
109 }
110
111 return RT_EOK;
112 }
113
114 static const struct rt_i2c_bus_device_ops am_i2c_ops =
115 {
116 rt_i2c_master_xfer,
117 RT_NULL,
118 rt_i2c_bus_control
119 };
120
121 #ifdef RT_USING_I2C0
122 static struct am_i2c_bus am_i2c_bus_0 =
123 {
124 {0},
125 AM_I2C0_IOM_INST
126 };
127 #endif
128
129 #ifdef RT_USING_I2C1
130 static struct am_i2c_bus am_i2c_bus_1 =
131 {
132 {1},
133 AM_I2C1_IOM_INST
134 };
135 #endif
136
137 #ifdef RT_USING_I2C2
138 static struct am_i2c_bus am_i2c_bus_2 =
139 {
140 {2},
141 AM_I2C2_IOM_INST
142 };
143 #endif
144
145 #ifdef RT_USING_I2C3
146 static struct am_i2c_bus am_i2c_bus_3 =
147 {
148 {3},
149 AM_I2C3_IOM_INST
150 };
151 #endif
152
153 #ifdef RT_USING_I2C4
154 static struct am_i2c_bus am_i2c_bus_4 =
155 {
156 {4},
157 AM_I2C4_IOM_INST
158 };
159 #endif
160
rt_i2c_init(void)161 int rt_i2c_init(void)
162 {
163 struct am_i2c_bus* am_i2c;
164
165 #ifdef RT_USING_I2C0
166 /* init i2c gpio */
167 am_hal_gpio_pin_config(I2C0_GPIO_SCL, I2C0_GPIO_CFG_SCK | AM_HAL_GPIO_PULL6K);
168 am_hal_gpio_pin_config(I2C0_GPIO_SDA, I2C0_GPIO_CFG_SDA | AM_HAL_GPIO_PULL6K);
169
170 /* Initialize IOM 0 in I2C mode at 100KHz */
171 am_hal_iom_pwrctrl_enable(AM_I2C0_IOM_INST);
172 g_sIOMConfig.ui32ClockFrequency = AM_HAL_IOM_100KHZ;
173 am_hal_iom_config(AM_I2C0_IOM_INST, &g_sIOMConfig);
174 am_hal_iom_enable(AM_I2C0_IOM_INST);
175
176 /* init i2c bus device */
177 am_i2c = &am_i2c_bus_0;
178 am_i2c->parent.ops = &am_i2c_ops;
179 rt_i2c_bus_device_register(&am_i2c->parent, "i2c0");
180 #endif
181
182 #ifdef RT_USING_I2C2
183 /* init i2c gpio */
184 am_hal_gpio_pin_config(I2C2_GPIO_SCL, I2C2_GPIO_CFG_SCK | AM_HAL_GPIO_PULL6K);
185 am_hal_gpio_pin_config(I2C2_GPIO_SDA, I2C2_GPIO_CFG_SDA | AM_HAL_GPIO_PULL6K);
186
187 /* Initialize IOM 2 in I2C mode at 400KHz */
188 am_hal_iom_pwrctrl_enable(AM_I2C2_IOM_INST);
189 g_sIOMConfig.ui32ClockFrequency = AM_HAL_IOM_400KHZ;
190 am_hal_iom_config(AM_I2C2_IOM_INST, &g_sIOMConfig);
191 am_hal_iom_enable(AM_I2C2_IOM_INST);
192
193 /* init i2c bus device */
194 am_i2c = &am_i2c_bus_2;
195 am_i2c->parent.ops = &am_i2c_ops;
196 rt_i2c_bus_device_register(&am_i2c->parent, "i2c2");
197 #endif
198
199 #ifdef RT_USING_I2C3
200 /* init i2c gpio */
201 am_hal_gpio_pin_config(I2C3_GPIO_SCL, I2C3_GPIO_CFG_SCK | AM_HAL_GPIO_PULL6K);
202 am_hal_gpio_pin_config(I2C3_GPIO_SDA, I2C3_GPIO_CFG_SDA | AM_HAL_GPIO_PULL6K);
203
204 /* Initialize IOM 3 in I2C mode at 400KHz */
205 am_hal_iom_pwrctrl_enable(AM_I2C3_IOM_INST);
206 g_sIOMConfig.ui32ClockFrequency = AM_HAL_IOM_400KHZ;
207 am_hal_iom_config(AM_I2C3_IOM_INST, &g_sIOMConfig);
208 am_hal_iom_enable(AM_I2C3_IOM_INST);
209
210 /* init i2c bus device */
211 am_i2c = &am_i2c_bus_3;
212 am_i2c->parent.ops = &am_i2c_ops;
213 rt_i2c_bus_device_register(&am_i2c->parent, "i2c3");
214 #endif
215
216 #ifdef RT_USING_I2C4
217 /* init i2c gpio */
218 am_hal_gpio_pin_config(I2C4_GPIO_SCL, I2C4_GPIO_CFG_SCK | AM_HAL_GPIO_PULL6K);
219 am_hal_gpio_pin_config(I2C4_GPIO_SDA, I2C4_GPIO_CFG_SDA | AM_HAL_GPIO_PULL6K);
220
221 /* Initialize IOM 4 in I2C mode at 400KHz */
222 am_hal_iom_pwrctrl_enable(AM_I2C4_IOM_INST);
223 g_sIOMConfig.ui32ClockFrequency = AM_HAL_IOM_400KHZ;
224 am_hal_iom_config(AM_I2C4_IOM_INST, &g_sIOMConfig);
225 am_hal_iom_enable(AM_I2C4_IOM_INST);
226
227 /* init i2c bus device */
228 am_i2c = &am_i2c_bus_4;
229 am_i2c->parent.ops = &am_i2c_ops;
230 rt_i2c_bus_device_register(&am_i2c->parent, "i2c4");
231 #endif
232
233 //rt_kprintf("i2c_init!\n");
234
235 return 0;
236 }
237 #ifdef RT_USING_COMPONENTS_INIT
238 INIT_BOARD_EXPORT(rt_i2c_init);
239 #endif
240
241 /*@}*/
242