1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2017-08-08 Yang the first version
9 * 2018-03-24 LaiYiKeTang add hardware iic
10 * 2019-04-22 tyustli add imxrt series support
11 *
12 */
13
14 #include <rtthread.h>
15
16 #ifdef BSP_USING_I2C
17
18 #define LOG_TAG "drv.i2c"
19 #include <drv_log.h>
20
21 #if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4) && !defined(BSP_USING_I2C5)&& !defined(BSP_USING_I2C6)
22 #error "Please define at least one BSP_USING_I2Cx"
23 #endif
24
25 #include <rtdevice.h>
26 #include "fsl_lpi2c.h"
27 #include "drv_i2c.h"
28
29 struct imxrt_i2c_bus
30 {
31 struct rt_i2c_bus_device parent;
32 LPI2C_Type *I2C;
33 struct rt_i2c_msg *msg;
34 rt_uint32_t msg_cnt;
35 volatile rt_uint32_t msg_ptr;
36 volatile rt_uint32_t dptr;
37 char *device_name;
38 #ifdef SOC_IMXRT1170_SERIES
39 clock_root_t clock_root;
40 #endif
41 };
42
43 #if defined (BSP_USING_I2C1)
44 #define I2C1BUS_NAME "i2c1"
45 #endif /*BSP_USING_I2C1*/
46
47 #if defined (BSP_USING_I2C2)
48 #define I2C2BUS_NAME "i2c2"
49 #endif /*BSP_USING_I2C2*/
50
51 #if !defined (MIMXRT1015_SERIES) /* imxrt1015 only have two i2c bus*/
52
53 #if defined (BSP_USING_I2C3)
54 #define I2C3BUS_NAME "i2c3"
55 #endif /*BSP_USING_I2C3*/
56
57 #if defined (BSP_USING_I2C4)
58 #define I2C4BUS_NAME "i2c4"
59 #endif /*BSP_USING_I2C4*/
60
61 #if defined (BSP_USING_I2C5)
62 #define I2C5BUS_NAME "i2c5"
63 #endif /*BSP_USING_I2C5*/
64
65 #if defined (BSP_USING_I2C6)
66 #define I2C6BUS_NAME "i2c6"
67 #endif /*BSP_USING_I2C6*/
68
69 #endif /* MIMXRT1015_SERIES */
70
71 /* Select USB1 PLL (360 MHz) as master lpi2c clock source */
72 #define LPI2C_CLOCK_SOURCE_SELECT (1U)
73 #ifdef SOC_IMXRT1170_SERIES
74 /* Clock divider for master lpi2c clock source */
75 #define LPI2C_CLOCK_SOURCE_DIVIDER (12U)
76 #else
77 #define LPI2C_CLOCK_SOURCE_DIVIDER (0U)
78
79 /* Get frequency of lpi2c clock */
80 #define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
81
82 #endif
83 #ifdef BSP_USING_I2C1
84 static struct imxrt_i2c_bus lpi2c1 =
85 {
86 .I2C = LPI2C1,
87 .device_name = I2C1BUS_NAME,
88 };
89 #endif /* RT_USING_HW_I2C1 */
90
91 #ifdef BSP_USING_I2C2
92 static struct imxrt_i2c_bus lpi2c2 =
93 {
94 .I2C = LPI2C2,
95 .device_name = I2C2BUS_NAME,
96 };
97 #endif /* RT_USING_HW_I2C2 */
98
99 #if !defined (MIMXRT1015_SERIES) /* imxrt1015 only have two i2c bus*/
100
101 #ifdef BSP_USING_I2C3
102 static struct imxrt_i2c_bus lpi2c3 =
103 {
104 .I2C = LPI2C3,
105 .device_name = I2C3BUS_NAME,
106 };
107 #endif /* RT_USING_HW_I2C3 */
108
109 #ifdef BSP_USING_I2C4
110 static struct imxrt_i2c_bus lpi2c4 =
111 {
112 .I2C = LPI2C4,
113 .device_name = I2C4BUS_NAME,
114 };
115 #endif /* RT_USING_HW_I2C4 */
116
117 #ifdef BSP_USING_I2C5
118 static struct imxrt_i2c_bus lpi2c5 =
119 {
120 .I2C = LPI2C5,
121 .device_name = I2C5BUS_NAME,
122 };
123 #endif /* RT_USING_HW_I2C5 */
124
125 #ifdef BSP_USING_I2C6
126 static struct imxrt_i2c_bus lpi2c6 =
127 {
128 .I2C = LPI2C6,
129 .device_name = I2C6BUS_NAME,
130 };
131 #endif /* RT_USING_HW_I2C6 */
132
133 #endif /* MIMXRT1015_SERIES */
134
135 #if (defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4) ||defined(BSP_USING_I2C5) || defined(BSP_USING_I2C6))
136
137 static rt_ssize_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
138 struct rt_i2c_msg msgs[],
139 rt_uint32_t num);
140 static rt_ssize_t imxrt_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
141 struct rt_i2c_msg msgs[],
142 rt_uint32_t num);
143 static rt_err_t imxrt_i2c_bus_control(struct rt_i2c_bus_device *bus,
144 int cmd,
145 void *args);
146
147 static const struct rt_i2c_bus_device_ops imxrt_i2c_ops =
148 {
149 .master_xfer = imxrt_i2c_mst_xfer,
150 .slave_xfer = imxrt_i2c_slv_xfer,
151 .i2c_bus_control = imxrt_i2c_bus_control,
152 };
153
imxrt_lpi2c_configure(struct imxrt_i2c_bus * bus,lpi2c_master_config_t * cfg)154 static rt_err_t imxrt_lpi2c_configure(struct imxrt_i2c_bus *bus, lpi2c_master_config_t *cfg)
155 {
156 RT_ASSERT(bus != RT_NULL);
157 RT_ASSERT(cfg != RT_NULL);
158
159 bus->parent.ops = &imxrt_i2c_ops;
160 #ifdef SOC_IMXRT1170_SERIES
161 clock_root_config_t rootCfg = {0};
162 rootCfg.mux = LPI2C_CLOCK_SOURCE_SELECT;
163 rootCfg.div = LPI2C_CLOCK_SOURCE_DIVIDER + 1;
164 CLOCK_SetRootClock(bus->clock_root, &rootCfg);
165 volatile uint32_t freq = CLOCK_GetRootClockFreq(bus->clock_root);
166 LPI2C_MasterInit(bus->I2C, cfg, freq);
167 #else
168 CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);
169 CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);
170 LPI2C_MasterInit(bus->I2C, cfg, LPI2C_CLOCK_FREQUENCY);
171 #endif
172
173 return RT_EOK;
174 }
175
LPI2C_MasterCheck(LPI2C_Type * base,uint32_t status)176 status_t LPI2C_MasterCheck(LPI2C_Type *base, uint32_t status)
177 {
178 status_t result = kStatus_Success;
179
180 /* Check for error. These errors cause a stop to automatically be sent. We must */
181 /* clear the errors before a new transfer can start. */
182 status &= 0x3c00;
183 if (status)
184 {
185 /* Select the correct error code. Ordered by severity, with bus issues first. */
186 if (status & kLPI2C_MasterPinLowTimeoutFlag)
187 {
188 result = kStatus_LPI2C_PinLowTimeout;
189 }
190 else if (status & kLPI2C_MasterArbitrationLostFlag)
191 {
192 result = kStatus_LPI2C_ArbitrationLost;
193 }
194 else if (status & kLPI2C_MasterNackDetectFlag)
195 {
196 result = kStatus_LPI2C_Nak;
197 }
198 else if (status & kLPI2C_MasterFifoErrFlag)
199 {
200 result = kStatus_LPI2C_FifoError;
201 }
202 else
203 {
204 assert(false);
205 }
206
207 /* Clear the flags. */
208 LPI2C_MasterClearStatusFlags(base, status);
209
210 /* Reset fifos. These flags clear automatically. */
211 base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
212 }
213
214 return result;
215 }
216
217 /*!
218 * @brief Wait until the tx fifo all empty.
219 * @param base The LPI2C peripheral base address.
220 * @retval #kStatus_Success
221 * @retval #kStatus_LPI2C_PinLowTimeout
222 * @retval #kStatus_LPI2C_ArbitrationLost
223 * @retval #kStatus_LPI2C_Nak
224 * @retval #kStatus_LPI2C_FifoError
225 */
LPI2C_MasterWaitForTxFifoAllEmpty(LPI2C_Type * base)226 static status_t LPI2C_MasterWaitForTxFifoAllEmpty(LPI2C_Type *base)
227 {
228 uint32_t status;
229 size_t txCount;
230
231 do
232 {
233 status_t result;
234
235 /* Get the number of words in the tx fifo and compute empty slots. */
236 LPI2C_MasterGetFifoCounts(base, NULL, &txCount);
237
238 /* Check for error flags. */
239 status = LPI2C_MasterGetStatusFlags(base);
240 result = LPI2C_MasterCheck(base, status);
241 if (result)
242 {
243 return result;
244 }
245 }
246
247 while (txCount);
248
249 return kStatus_Success;
250 }
251
imxrt_i2c_mst_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)252 static rt_ssize_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
253 struct rt_i2c_msg msgs[],
254 rt_uint32_t num)
255 {
256 struct imxrt_i2c_bus *imxrt_i2c;
257 rt_size_t i;
258 RT_ASSERT(bus != RT_NULL);
259 imxrt_i2c = (struct imxrt_i2c_bus *) bus;
260
261 imxrt_i2c->msg = msgs;
262 imxrt_i2c->msg_ptr = 0;
263 imxrt_i2c->msg_cnt = num;
264 imxrt_i2c->dptr = 0;
265
266 for (i = 0; i < num; i++)
267 {
268 if (imxrt_i2c->msg[i].flags & RT_I2C_RD)
269 {
270 if ((imxrt_i2c->msg[i].flags & RT_I2C_NO_START) != RT_I2C_NO_START)
271 {
272 if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success)
273 {
274 i = 0;
275 break;
276 }
277
278 while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag)
279 {
280 }
281
282 if (LPI2C_MasterRepeatedStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success)
283 {
284 i = 0;
285 break;
286 }
287 }
288 else
289 {
290 if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success)
291 {
292 i = 0;
293 break;
294 }
295
296 while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag)
297 {
298 }
299 }
300
301 if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success)
302 {
303 i = 0;
304 break;
305 }
306
307 while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag)
308 {
309 }
310
311 if (LPI2C_MasterReceive(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success)
312 {
313 i = 0;
314 break;
315 }
316 }
317 else
318 {
319 if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success)
320 {
321 i = 0;
322 break;
323 }
324
325 // while((LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterBusBusyFlag))
326 // {
327 // }
328 if(LPI2C_MasterWaitForTxFifoAllEmpty(imxrt_i2c->I2C) != kStatus_Success)
329 {
330 i = 0;
331 break;
332 }
333
334 if (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag)
335 {
336 i = 0;
337 break;
338 }
339
340 if (LPI2C_MasterSend(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success)
341 {
342 i = 0;
343 break;
344 }
345
346 if (LPI2C_MasterWaitForTxFifoAllEmpty(imxrt_i2c->I2C) != kStatus_Success)
347 {
348 i = 0;
349 break;
350 }
351 }
352
353 if (LPI2C_MasterStop(imxrt_i2c->I2C) != kStatus_Success)
354 {
355 i = 0;
356 }
357
358 }
359
360 imxrt_i2c->msg = RT_NULL;
361 imxrt_i2c->msg_ptr = 0;
362 imxrt_i2c->msg_cnt = 0;
363 imxrt_i2c->dptr = 0;
364
365 return i;
366 }
367
imxrt_i2c_slv_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)368 static rt_ssize_t imxrt_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
369 struct rt_i2c_msg msgs[],
370 rt_uint32_t num)
371 {
372 return 0;
373 }
imxrt_i2c_bus_control(struct rt_i2c_bus_device * bus,int cmd,void * args)374 static rt_err_t imxrt_i2c_bus_control(struct rt_i2c_bus_device *bus,
375 int cmd,
376 void *args)
377 {
378 return -RT_ERROR;
379 }
380
381 #endif
382
rt_hw_i2c_init(void)383 int rt_hw_i2c_init(void)
384 {
385 lpi2c_master_config_t masterConfig = {0};
386
387 #if defined(BSP_USING_I2C1)
388 LPI2C_MasterGetDefaultConfig(&masterConfig);
389 #if defined(HW_I2C1_BADURATE_400kHZ)
390 masterConfig.baudRate_Hz = 400000U;
391 #elif defined(HW_I2C1_BADURATE_100kHZ)
392 masterConfig.baudRate_Hz = 100000U;
393 #endif /*HW_I2C1_BADURATE_400kHZ*/
394 imxrt_lpi2c_configure(&lpi2c1, &masterConfig);
395 rt_i2c_bus_device_register(&lpi2c1.parent, lpi2c1.device_name);
396 #endif /* BSP_USING_I2C1 */
397
398 #if defined(BSP_USING_I2C2)
399 LPI2C_MasterGetDefaultConfig(&masterConfig);
400 #if defined(HW_I2C2_BADURATE_400kHZ)
401 masterConfig.baudRate_Hz = 400000U;
402 #elif defined(HW_I2C2_BADURATE_100kHZ)
403 masterConfig.baudRate_Hz = 100000U;
404 #endif /* HW_I2C2_BADURATE_400kHZ */
405 imxrt_lpi2c_configure(&lpi2c2, &masterConfig);
406 rt_i2c_bus_device_register(&lpi2c2.parent, lpi2c2.device_name);
407 #endif /* BSP_USING_I2C2 */
408
409 #if !defined(MIMXRT1015_SERIES) /* imxrt1015 only have two i2c bus*/
410
411 #if defined(BSP_USING_I2C3)
412 LPI2C_MasterGetDefaultConfig(&masterConfig);
413 #if defined(HW_I2C3_BADURATE_400kHZ)
414 masterConfig.baudRate_Hz = 400000U;
415 #elif defined(HW_I2C3_BADURATE_100kHZ)
416 masterConfig.baudRate_Hz = 100000U;
417 #endif /* HW_I2C3_BADURATE_400kHZ */
418 imxrt_lpi2c_configure(&lpi2c3, &masterConfig);
419 rt_i2c_bus_device_register(&lpi2c3.parent, lpi2c3.device_name);
420 #endif /* BSP_USING_I2C3 */
421
422 #if defined(BSP_USING_I2C4)
423 LPI2C_MasterGetDefaultConfig(&masterConfig);
424 #if defined(HW_I2C4_BADURATE_400kHZ)
425 masterConfig.baudRate_Hz = 400000U;
426 #elif defined(HW_I2C4_BADURATE_100kHZ)
427 masterConfig.baudRate_Hz = 100000U;
428 #endif /* HW_I2C4_BADURATE_400kHZ */
429 imxrt_lpi2c_configure(&lpi2c4, &masterConfig);
430 rt_i2c_bus_device_register(&lpi2c4.parent, lpi2c4.device_name);
431 #endif /* BSP_USING_I2C4 */
432
433 #if defined(BSP_USING_I2C5)
434 LPI2C_MasterGetDefaultConfig(&masterConfig);
435 #if defined(HW_I2C5_BADURATE_400kHZ)
436 masterConfig.baudRate_Hz = 400000U;
437 #elif defined(HW_I2C5_BADURATE_100kHZ)
438 masterConfig.baudRate_Hz = 100000U;
439 #endif /* HW_I2C5_BADURATE_400kHZ */
440 lpi2c5.clock_root = kCLOCK_Root_Lpi2c5;
441 imxrt_lpi2c_configure(&lpi2c5, &masterConfig);
442 rt_i2c_bus_device_register(&lpi2c5.parent, lpi2c5.device_name);
443 #endif /* BSP_USING_I2C5 */
444
445 #if defined(BSP_USING_I2C6)
446 LPI2C_MasterGetDefaultConfig(&masterConfig);
447 #if defined(HW_I2C6_BADURATE_400kHZ)
448 masterConfig.baudRate_Hz = 400000U;
449 #elif defined(HW_I2C6_BADURATE_100kHZ)
450 masterConfig.baudRate_Hz = 100000U;
451 #endif /* HW_I2C6_BADURATE_400kHZ */
452 lpi2c6.clock_root = kCLOCK_Root_Lpi2c6;
453 imxrt_lpi2c_configure(&lpi2c6, &masterConfig);
454 rt_i2c_bus_device_register(&lpi2c6.parent, lpi2c6.device_name);
455 #endif /* BSP_USING_I2C6 */
456
457
458 #endif /* MIMXRT1015_SERIES */
459
460 return 0;
461 }
462
463 INIT_DEVICE_EXPORT(rt_hw_i2c_init);
464
465 #endif /* BSP_USING_I2C */
466