1 /*
2  * Copyright (c) 2006-2025, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  */
7 
8 #include "drv_hw_i2c.h"
9 
10 
11 #ifdef RT_USING_I2C
12 
13 #define LOG_TAG              "drv.i2c"
14 #include <rtdbg.h>
15 
16 static const struct gd32_i2c_config i2c_configs[] =
17 {
18 #ifdef BSP_USING_HW_I2C0
19      {
20         .i2c_periph = I2C0, .device_name = "i2c0", .periph_clk = RCU_I2C0, .i2c_clock_hz = BSP_HW_I2C0_CLOCK_SPEED,
21         .scl_clk = RCU_GPIOB, .scl_port = GPIOB, .scl_pin = GPIO_PIN_6, .scl_af = GPIO_AF_1,
22         .sda_clk = RCU_GPIOB, .sda_port = GPIOB, .sda_pin = GPIO_PIN_7, .sda_af = GPIO_AF_1,
23         .ev_irq_type = I2C0_EV_IRQn, .er_irq_type = I2C0_ER_IRQn,
24     },
25 #endif
26 #ifdef BSP_USING_HW_I2C1
27     {
28         .i2c_periph = I2C1, .device_name = "i2c1", .periph_clk = RCU_I2C1, .i2c_clock_hz = BSP_HW_I2C1_CLOCK_SPEED,
29         .scl_clk = RCU_GPIOB, .scl_port = GPIOB, .scl_pin = GPIO_PIN_10, .scl_af = GPIO_AF_1,
30         .sda_clk = RCU_GPIOB, .sda_port = GPIOB, .sda_pin = GPIO_PIN_11, .sda_af = GPIO_AF_1,
31         .ev_irq_type = I2C1_EV_IRQn, .er_irq_type = I2C1_ER_IRQn,
32     },
33 #endif
34 };
35 
36 static struct gd32_i2c i2c_objs[sizeof(i2c_configs) / sizeof(i2c_configs[0])];
37 
38 #define I2C_GD32_ERR_BERR (1U << 0)  /* Bus error */
39 #define I2C_GD32_ERR_LARB (1U << 1)  /* Arbitration lost */
40 #define I2C_GD32_ERR_AERR (1U << 2)  /* No ACK received */
41 #define I2C_GD32_ERR_BUSY (1U << 4)  /* I2C bus busy */
i2c_enable_interrupts(uint32_t i2c_periph)42 static inline void i2c_enable_interrupts(uint32_t i2c_periph)
43 {
44     i2c_interrupt_enable(i2c_periph, I2C_INT_ERR);
45     i2c_interrupt_enable(i2c_periph, I2C_INT_EV);
46     i2c_interrupt_enable(i2c_periph, I2C_INT_BUF);
47 }
48 
i2c_disable_interrupts(uint32_t i2c_periph)49 static inline void i2c_disable_interrupts(uint32_t i2c_periph)
50 {
51     i2c_interrupt_disable(i2c_periph, I2C_INT_ERR);
52     i2c_interrupt_disable(i2c_periph, I2C_INT_EV);
53     i2c_interrupt_disable(i2c_periph, I2C_INT_BUF);
54 }
55 
i2c_log_error(struct gd32_i2c * i2c_dev)56 static inline void i2c_log_error(struct gd32_i2c *i2c_dev)
57 {
58     if (i2c_dev->errs & I2C_GD32_ERR_BERR) LOG_E("[%s] Bus error", i2c_dev->config->device_name);
59     if (i2c_dev->errs & I2C_GD32_ERR_LARB) LOG_E("[%s] Arbitration lost", i2c_dev->config->device_name);
60     if (i2c_dev->errs & I2C_GD32_ERR_AERR) LOG_E("[%s] No ACK received", i2c_dev->config->device_name);
61     if (i2c_dev->errs & I2C_GD32_ERR_BUSY) LOG_E("[%s] I2C bus is busy", i2c_dev->config->device_name);
62 }
63 
gd32_i2c_xfer_read(struct gd32_i2c * i2c_obj)64 static inline void gd32_i2c_xfer_read(struct gd32_i2c *i2c_obj)
65 {
66     const struct gd32_i2c_config *cfg = i2c_obj->config;
67     rt_uint8_t read_byte;
68 
69     i2c_obj->current->len--;
70     read_byte = I2C_DATA(cfg->i2c_periph);
71     *i2c_obj->current->buf = read_byte;
72 
73     LOG_D("[%s] < Read byte: 0x%02X", cfg->device_name, read_byte);
74 
75     i2c_obj->current->buf++;
76 
77     if ((i2c_obj->xfer_len > 0U) && (i2c_obj->current->len == 0U))
78     {
79         i2c_obj->current++;
80     }
81 }
82 
gd32_i2c_xfer_write(struct gd32_i2c * i2c_obj)83 static inline void gd32_i2c_xfer_write(struct gd32_i2c *i2c_obj)
84 {
85     const struct gd32_i2c_config *cfg = i2c_obj->config;
86 
87     rt_uint8_t write_byte = *i2c_obj->current->buf;
88     LOG_D("[%s] > Write byte: 0x%02X", cfg->device_name, write_byte);
89 
90     i2c_obj->current->len--;
91     I2C_DATA(cfg->i2c_periph) = *i2c_obj->current->buf;
92     i2c_obj->current->buf++;
93 
94     if ((i2c_obj->xfer_len > 0U) && (i2c_obj->current->len == 0U))
95     {
96         i2c_obj->current++;
97     }
98 }
99 
gd32_i2c_handle_tbe(struct gd32_i2c * i2c_obj)100 static void gd32_i2c_handle_tbe(struct gd32_i2c *i2c_obj)
101 {
102     const struct gd32_i2c_config *cfg = i2c_obj->config;
103     LOG_D("[%s] TBE event: xfer_len=%d", cfg->device_name, i2c_obj->xfer_len);
104 
105     if (i2c_obj->xfer_len > 0U)
106     {
107         i2c_obj->xfer_len--;
108         if (i2c_obj->xfer_len == 0U)
109         {
110             LOG_D("[%s] Last byte to send, disabling BUFIE, waiting for BTC.", cfg->device_name);
111             I2C_CTL1(cfg->i2c_periph) &= ~I2C_CTL1_BUFIE;
112         }
113         gd32_i2c_xfer_write(i2c_obj);
114     }
115     else
116     {
117         LOG_D("[%s] TBE indicates all data sent. Generating STOP.", cfg->device_name);
118         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP;
119         rt_completion_done(&i2c_obj->sync_sem);
120     }
121 }
122 
gd32_i2c_handle_rbne(struct gd32_i2c * i2c_obj)123 static void gd32_i2c_handle_rbne(struct gd32_i2c *i2c_obj)
124 {
125     const struct gd32_i2c_config *cfg = i2c_obj->config;
126     LOG_D("[%s] RBNE event: xfer_len=%d", cfg->device_name, i2c_obj->xfer_len);
127 
128     switch (i2c_obj->xfer_len)
129     {
130     case 0:
131         LOG_W("[%s] Unexpected RBNE, waking thread.", cfg->device_name);
132         rt_completion_done(&i2c_obj->sync_sem);
133         break;
134     case 1:
135         i2c_obj->xfer_len--;
136         gd32_i2c_xfer_read(i2c_obj);
137         LOG_D("[%s] RBNE: Last byte received, waking thread.", cfg->device_name);
138         rt_completion_done(&i2c_obj->sync_sem);
139         break;
140     case 2:
141     case 3:
142         LOG_D("[%s] RBNE: %d bytes left, disabling BUFIE, waiting for BTC.", cfg->device_name, i2c_obj->xfer_len);
143         I2C_CTL1(cfg->i2c_periph) &= ~I2C_CTL1_BUFIE;
144         break;
145     default:
146         i2c_obj->xfer_len--;
147         gd32_i2c_xfer_read(i2c_obj);
148         break;
149     }
150 }
151 
gd32_i2c_handle_btc(struct gd32_i2c * i2c_obj)152 static void gd32_i2c_handle_btc(struct gd32_i2c *i2c_obj)
153 {
154     const struct gd32_i2c_config *cfg = i2c_obj->config;
155     LOG_D("[%s] BTC event: xfer_len=%d, flags=0x%X", cfg->device_name, i2c_obj->xfer_len, i2c_obj->current->flags);
156 
157     if (i2c_obj->current->flags & RT_I2C_RD)
158     {
159         switch (i2c_obj->xfer_len)
160         {
161         case 2:
162             LOG_D("[%s] BTC: N=2, generating STOP.", cfg->device_name);
163             I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP;
164             i2c_obj->xfer_len -= 2;
165             gd32_i2c_xfer_read(i2c_obj);
166             gd32_i2c_xfer_read(i2c_obj);
167             rt_completion_done(&i2c_obj->sync_sem);
168             break;
169         case 3:
170             LOG_D("[%s] BTC: N=3, clearing ACKEN for NACK.", cfg->device_name);
171             I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_ACKEN;
172             i2c_obj->xfer_len--;
173             gd32_i2c_xfer_read(i2c_obj);
174             break;
175         default:
176             LOG_W("[%s] Unexpected BTC in read mode, handling as RBNE.", cfg->device_name);
177             gd32_i2c_handle_rbne(i2c_obj);
178             break;
179         }
180     }
181     else
182     {
183         LOG_D("[%s] BTC in write mode, means last byte sent.", cfg->device_name);
184         gd32_i2c_handle_tbe(i2c_obj);
185     }
186 }
187 
gd32_i2c_handle_addsend(struct gd32_i2c * i2c_obj)188 static void gd32_i2c_handle_addsend(struct gd32_i2c *i2c_obj)
189 {
190     const struct gd32_i2c_config *cfg = i2c_obj->config;
191     LOG_D("[%s] ADDSEND event: xfer_len=%d, flags=0x%X, is_restart=%d", cfg->device_name, i2c_obj->xfer_len, i2c_obj->current->flags, i2c_obj->is_restart);
192 
193     if ((i2c_obj->current->flags & RT_I2C_RD) && (i2c_obj->xfer_len <= 1U))
194     {
195         LOG_D("[%s] ADDSEND: N<=1 read, clearing ACKEN.", cfg->device_name);
196         I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_ACKEN;
197     }
198 
199     (void)I2C_STAT0(cfg->i2c_periph);
200     (void)I2C_STAT1(cfg->i2c_periph);
201 
202     if (i2c_obj->is_restart)
203     {
204         i2c_obj->is_restart = RT_FALSE;
205         i2c_obj->current->flags |= RT_I2C_RD;
206         LOG_D("[%s] ADDSEND: 10-bit read restart. Generating RESTART.", cfg->device_name);
207         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_START;
208         return;
209     }
210 
211     if ((i2c_obj->current->flags & RT_I2C_RD) && (i2c_obj->xfer_len == 1U))
212     {
213         LOG_D("[%s] ADDSEND: N=1 read, generating STOP.", cfg->device_name);
214         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP;
215     }
216 }
217 
gd32_i2c_event_handler(struct gd32_i2c * i2c_obj)218 static void gd32_i2c_event_handler(struct gd32_i2c *i2c_obj)
219 {
220     const struct gd32_i2c_config *cfg;
221     uint32_t stat0;
222 
223     RT_ASSERT(i2c_obj != RT_NULL);
224     cfg = i2c_obj->config;
225 
226     stat0 = I2C_STAT0(cfg->i2c_periph);
227     LOG_D("[%s] EV_IRQ: STAT0=0x%08X", cfg->device_name, stat0);
228 
229     if (stat0 & I2C_STAT0_SBSEND)
230     {
231         uint8_t addr_byte;
232         if (i2c_obj->current->flags & RT_I2C_RD)
233         {
234             addr_byte = (i2c_obj->addr1 << 1) | 1;
235         }
236         else
237         {
238             addr_byte = (i2c_obj->addr1 << 1) | 0;
239         }
240         LOG_D("[%s] SBSEND: Sending address byte 0x%02X", cfg->device_name, addr_byte);
241         I2C_DATA(cfg->i2c_periph) = addr_byte;
242     }
243     else if (stat0 & I2C_STAT0_ADD10SEND)
244     {
245         LOG_D("[%s] ADD10SEND: Sending 2nd address byte 0x%02X", cfg->device_name, i2c_obj->addr2);
246         I2C_DATA(cfg->i2c_periph) = i2c_obj->addr2;
247     }
248     else if (stat0 & I2C_STAT0_ADDSEND)
249     {
250         gd32_i2c_handle_addsend(i2c_obj);
251     }
252     else if (stat0 & I2C_STAT0_BTC)
253     {
254         gd32_i2c_handle_btc(i2c_obj);
255     }
256     else if (stat0 & I2C_STAT0_RBNE)
257     {
258         gd32_i2c_handle_rbne(i2c_obj);
259     }
260     else if (stat0 & I2C_STAT0_TBE)
261     {
262         gd32_i2c_handle_tbe(i2c_obj);
263     }
264 }
265 
gd32_i2c_error_handler(struct gd32_i2c * i2c_obj)266 void gd32_i2c_error_handler(struct gd32_i2c *i2c_obj)
267 {
268     const struct gd32_i2c_config *cfg;
269     uint32_t stat0;
270 
271     RT_ASSERT(i2c_obj != RT_NULL);
272     cfg = i2c_obj->config;
273 
274     stat0 = I2C_STAT0(cfg->i2c_periph);
275     LOG_E("[%s] ER_IRQ: STAT0=0x%08X", cfg->device_name, stat0);
276 
277     if (stat0 & I2C_STAT0_BERR)
278     {
279         I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_BERR;
280         i2c_obj->errs |= I2C_GD32_ERR_BERR;
281     }
282 
283     if (stat0 & I2C_STAT0_LOSTARB)
284     {
285         I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_LOSTARB;
286         i2c_obj->errs |= I2C_GD32_ERR_LARB;
287     }
288 
289     if (stat0 & I2C_STAT0_AERR)
290     {
291         I2C_STAT0(cfg->i2c_periph) &= ~I2C_STAT0_AERR;
292         i2c_obj->errs |= I2C_GD32_ERR_AERR;
293     }
294 
295     if (i2c_obj->errs != 0)
296     {
297         LOG_D("[%s] Error detected, sending STOP and waking thread.", cfg->device_name);
298         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP;
299         rt_completion_done(&i2c_obj->sync_sem);
300     }
301 }
302 
gd32_i2c_master_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)303 static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
304 {
305     struct gd32_i2c *i2c_dev;
306     const struct gd32_i2c_config *cfg;
307     rt_ssize_t i, itr;
308     rt_err_t result = RT_EOK;
309 
310     RT_ASSERT(bus != RT_NULL);
311     RT_ASSERT(msgs != RT_NULL);
312     RT_ASSERT(num > 0);
313 
314     i2c_dev = rt_container_of(bus, struct gd32_i2c, parent);
315     cfg = i2c_dev->config;
316 
317     LOG_D("[%s] master_xfer: num_msgs=%d", cfg->device_name, num);
318 
319     for (i = 0; i < num; i++)
320     {
321         if ((i < num - 1) && !(msgs[i].flags & RT_I2C_NO_STOP))
322         {
323             LOG_E("[%s] Only the last message can have a STOP signal", cfg->device_name);
324             return -RT_EINVAL;
325         }
326 
327         if (msgs[i].len == 0 || msgs[i].buf == RT_NULL)
328         {
329             LOG_E("[%s] Invalid message buffer or length at index %d", cfg->device_name, i);
330             return -RT_EINVAL;
331         }
332     }
333 
334     rt_mutex_take(&i2c_dev->bus_mutex, RT_WAITING_FOREVER);
335 
336     I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_I2CEN;
337 
338     for (i = 0; i < num; i = itr)
339     {
340         LOG_D("[%s] Processing msg segment starting at index %d", cfg->device_name, i);
341         i2c_dev->current = &msgs[i];
342         i2c_dev->xfer_len = msgs[i].len;
343         rt_uint16_t current_addr = i2c_dev->current->addr;
344 
345         for (itr = i + 1; itr < num; itr++)
346         {
347             if ((msgs[itr].flags & RT_I2C_RD) != (i2c_dev->current->flags & RT_I2C_RD) ||
348                 msgs[itr].addr != current_addr)
349             {
350                 break;
351             }
352             i2c_dev->xfer_len += msgs[itr].len;
353         }
354         LOG_D("[%s] Merged %d msgs. Total len=%d, addr=0x%X, flags=0x%X",
355               cfg->device_name, itr - i, i2c_dev->xfer_len, current_addr, i2c_dev->current->flags);
356 
357         LOG_D("[%s] Checking for bus busy...", cfg->device_name);
358         if (I2C_STAT1(cfg->i2c_periph) & I2C_STAT1_I2CBSY)
359         {
360             LOG_E("[%s] Bus is busy!", cfg->device_name);
361             i2c_dev->errs = I2C_GD32_ERR_BUSY;
362             result = -RT_EBUSY;
363             break;
364         }
365 
366         if (i2c_dev->current->flags & RT_I2C_ADDR_10BIT)
367         {
368             i2c_dev->addr1 = 0xF0 | ((current_addr >> 8) & 0x03);
369             i2c_dev->addr2 = current_addr & 0xFF;
370             LOG_D("[%s] 10-bit address: 0x%X -> addr1=0x%X, addr2=0x%X", cfg->device_name, current_addr, i2c_dev->addr1, i2c_dev->addr2);
371         }
372         else
373         {
374             i2c_dev->addr1 = current_addr & 0x7F;
375         }
376 
377         i2c_dev->errs = 0;
378         i2c_dev->is_restart = RT_FALSE;
379         rt_completion_init(&i2c_dev->sync_sem);
380 
381         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_ACKEN;
382 
383         if ((i2c_dev->current->flags & RT_I2C_RD) && (i2c_dev->current->flags & RT_I2C_ADDR_10BIT))
384         {
385             LOG_D("[%s] Preparing for 10-bit read restart.", cfg->device_name);
386             i2c_dev->is_restart = RT_TRUE;
387             i2c_dev->current->flags &= ~RT_I2C_RD;
388         }
389 
390         if ((i2c_dev->current->flags & RT_I2C_RD) && (i2c_dev->xfer_len == 2))
391         {
392             LOG_D("[%s] N=2 read, setting POAP.", cfg->device_name);
393             I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_POAP;
394         }
395 
396         LOG_D("[%s] Generating START, enabling IRQs, waiting for completion...", cfg->device_name);
397         i2c_enable_interrupts(cfg->i2c_periph);
398         I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_START;
399 
400         result = rt_completion_wait(&i2c_dev->sync_sem, bus->timeout);
401 
402         if (i2c_dev->is_restart == RT_TRUE)
403         {
404             i2c_dev->current->flags |= RT_I2C_RD;
405         }
406 
407         I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_POAP;
408         i2c_disable_interrupts(cfg->i2c_periph);
409 
410         if (result != RT_EOK)
411         {
412             LOG_E("[%s] I2C transaction timeout!", cfg->device_name);
413             result = -RT_ETIMEOUT;
414             I2C_CTL0(cfg->i2c_periph) |= I2C_CTL0_STOP;
415             break;
416         }
417 
418         if (i2c_dev->errs != 0)
419         {
420             LOG_E("[%s] Hardware error detected by ISR.", cfg->device_name);
421             i2c_log_error(i2c_dev);
422             result = -RT_EIO;
423             break;
424         }
425         LOG_D("[%s] Transaction segment completed successfully.", cfg->device_name);
426     }
427 
428     if (result == RT_EOK)
429     {
430         if (!(msgs[num - 1].flags & RT_I2C_NO_STOP))
431         {
432             LOG_D("[%s] Last message, Waiting STOP.", cfg->device_name);
433             rt_uint32_t timeout = 1000;
434             while (I2C_STAT1(cfg->i2c_periph) & I2C_STAT1_I2CBSY && timeout--)
435             {
436                 rt_hw_us_delay(1);
437             }
438         }
439         else
440         {
441             LOG_D("[%s] Last message has NO_STOP flag, leaving bus active.", cfg->device_name);
442         }
443     }
444 
445     I2C_CTL0(cfg->i2c_periph) &= ~I2C_CTL0_I2CEN;
446 
447     rt_mutex_release(&i2c_dev->bus_mutex);
448 
449     LOG_D("[%s] master_xfer exiting with code: %d", cfg->device_name, (result == RT_EOK) ? i : result);
450     if (result == RT_EOK)
451     {
452         return i;
453     }
454     else
455     {
456         return result;
457     }
458 }
459 
460 
_get_i2c_obj(uint32_t i2c_periph)461 static struct gd32_i2c *_get_i2c_obj(uint32_t i2c_periph)
462 {
463     for (size_t i = 0; i < sizeof(i2c_objs) / sizeof(i2c_objs[0]); i++)
464     {
465         if (i2c_objs[i].config->i2c_periph == i2c_periph)
466         {
467             return &i2c_objs[i];
468         }
469     }
470     /* Should not happen in a correctly configured system. */
471     LOG_E("Cannot find i2c_obj for periph: 0x%08X", i2c_periph);
472     return RT_NULL;
473 }
474 
475 #ifdef BSP_USING_HW_I2C0
I2C0_EV_IRQHandler(void)476 void I2C0_EV_IRQHandler(void)
477 {
478     rt_interrupt_enter();
479 
480     struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C0);
481     if (i2c_obj)
482     {
483         gd32_i2c_event_handler(i2c_obj);
484     }
485 
486     rt_interrupt_leave();
487 }
488 
I2C0_ER_IRQHandler(void)489 void I2C0_ER_IRQHandler(void)
490 {
491     rt_interrupt_enter();
492 
493     struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C0);
494     if (i2c_obj)
495     {
496         gd32_i2c_error_handler(i2c_obj);
497     }
498 
499     rt_interrupt_leave();
500 }
501 #endif
502 
503 
504 #ifdef BSP_USING_HW_I2C1
I2C1_EV_IRQHandler(void)505 void I2C1_EV_IRQHandler(void)
506 {
507     rt_interrupt_enter();
508 
509     struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C1);
510     if (i2c_obj)
511     {
512         gd32_i2c_event_handler(i2c_obj);
513     }
514 
515     rt_interrupt_leave();
516 }
517 
I2C1_ER_IRQHandler(void)518 void I2C1_ER_IRQHandler(void)
519 {
520     rt_interrupt_enter();
521 
522     struct gd32_i2c *i2c_obj = _get_i2c_obj(I2C1);
523     if (i2c_obj)
524     {
525         gd32_i2c_error_handler(i2c_obj);
526     }
527 
528     rt_interrupt_leave();
529 }
530 #endif
531 
532 
533 static const struct rt_i2c_bus_device_ops gd32_i2c_ops =
534 {
535     .master_xfer = gd32_i2c_master_xfer,
536     .slave_xfer  = RT_NULL,
537     .i2c_bus_control = RT_NULL,
538 };
539 
rt_hw_i2c_init(void)540 int rt_hw_i2c_init(void)
541 {
542     rt_size_t obj_num = sizeof(i2c_objs) / sizeof(struct gd32_i2c);
543     rt_err_t result;
544 
545     for (int i = 0; i < obj_num; i++)
546     {
547         const struct gd32_i2c_config *config = &i2c_configs[i];
548         struct gd32_i2c *i2c_obj = &i2c_objs[i];
549 
550         LOG_D("Initializing %s...", config->device_name);
551 
552         i2c_obj->config = config;
553         i2c_obj->parent.ops = &gd32_i2c_ops;
554         i2c_obj->parent.timeout = RT_TICK_PER_SECOND;
555 
556         rcu_periph_clock_enable(config->scl_clk);
557         if (config->scl_clk != config->sda_clk)
558         {
559             rcu_periph_clock_enable(config->sda_clk);
560         }
561         rcu_periph_clock_enable(config->periph_clk);
562 
563         gpio_af_set(config->scl_port, config->scl_af, config->scl_pin);
564         gpio_mode_set(config->scl_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, config->scl_pin);
565         gpio_output_options_set(config->scl_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, config->scl_pin);
566 
567         gpio_af_set(config->sda_port, config->sda_af, config->sda_pin);
568         gpio_mode_set(config->sda_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, config->sda_pin);
569         gpio_output_options_set(config->sda_port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, config->sda_pin);
570 
571         i2c_deinit(config->i2c_periph);
572         i2c_clock_config(config->i2c_periph, config->i2c_clock_hz, I2C_DTCY_2);
573         i2c_mode_addr_config(config->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0);
574         i2c_enable(config->i2c_periph);
575         i2c_ack_config(config->i2c_periph, I2C_ACK_ENABLE);
576 
577         nvic_irq_enable(config->ev_irq_type, 2);
578         nvic_irq_enable(config->er_irq_type, 1);
579 
580         result = rt_i2c_bus_device_register(&i2c_obj->parent, config->device_name);
581         if (result != RT_EOK)
582         {
583             LOG_E("Failed to register i2c bus %s", config->device_name);
584             return result;
585         }
586 
587         rt_mutex_init(&i2c_obj->bus_mutex,
588                   config->device_name,
589                   RT_IPC_FLAG_FIFO);
590 
591         rt_completion_init(&i2c_obj->sync_sem);
592 
593         LOG_I("I2C bus %s registered successfully.", config->device_name);
594     }
595     return RT_EOK;
596 }
597 INIT_BOARD_EXPORT(rt_hw_i2c_init);
598 
599 #endif /* RT_USING_I2C */
600 
601