1 /*
2  * Copyright (c) 2006-2020, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-04-27     hqfang       first implementation.
9  */
10 
11 #include "drv_i2c.h"
12 
13 #ifdef RT_USING_I2C
14 
15 #if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1)
16     #error "Please define at least one BSP_USING_I2Cx"
17     /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable I2C */
18 #endif
19 
20 static struct gd32_i2c_config i2c_config[] =
21 {
22 #ifdef BSP_USING_I2C0
23     {
24         "i2c0",
25         I2C0,
26         100000,
27     },
28 #endif
29 #ifdef BSP_USING_I2C1
30     {
31         "i2c1",
32         I2C1,
33         100000,
34     },
35 #endif
36 };
37 
38 static struct gd32_i2c i2c_obj[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0};
39 
40 #define GD32_I2C_TIMEOUT    10
41 
gd32_i2c_read(rt_uint32_t i2c_periph,rt_uint16_t slave_address,rt_uint8_t * p_buffer,rt_uint16_t cnt)42 static int gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint16_t slave_address, rt_uint8_t *p_buffer, rt_uint16_t cnt)
43 {
44     /* send slave address to I2C bus */
45     i2c_master_addressing(i2c_periph, slave_address << 1, I2C_RECEIVER);
46 
47     /* wait until ADDSEND bit is set */
48     while (!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND));
49 
50     /* clear the ADDSEND bit */
51     i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND);
52 
53     /* while there is data to be read */
54     while (cnt)
55     {
56         if (cnt == 1)
57         {
58             // Send NACK for last 1 byte receive
59             i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
60         }
61         /* wait until the RBNE bit is set */
62         while (i2c_flag_get(i2c_periph, I2C_FLAG_RBNE) == RESET);
63 
64         /* read a byte from i2c */
65         *p_buffer = i2c_data_receive(i2c_periph);
66 
67         /* point to the next location where the byte read will be saved */
68         p_buffer++;
69 
70         /* decrement the read bytes counter */
71         cnt--;
72     }
73 
74     return 0;
75 }
76 
gd32_i2c_write(rt_uint32_t i2c_periph,uint16_t slave_address,uint8_t * p_buffer,uint16_t cnt)77 static int gd32_i2c_write(rt_uint32_t i2c_periph, uint16_t slave_address, uint8_t *p_buffer, uint16_t cnt)
78 {
79     /* send slave address to I2C bus */
80     i2c_master_addressing(i2c_periph, slave_address << 1, I2C_TRANSMITTER);
81 
82     /* wait until ADDSEND bit is set */
83     while (!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND));
84 
85     /* clear the ADDSEND bit */
86     i2c_flag_clear(i2c_periph, I2C_FLAG_ADDSEND);
87 
88     /* wait until the transmit data buffer is empty */
89     while (SET != i2c_flag_get(i2c_periph, I2C_FLAG_TBE));
90 
91     /* while there is data to be read */
92     while (cnt)
93     {
94         i2c_data_transmit(i2c_periph, *p_buffer);
95 
96         /* point to the next byte to be written */
97         p_buffer++;
98 
99         /* decrement the write bytes counter */
100         cnt--;
101 
102         /* wait until BTC bit is set */
103         while (!i2c_flag_get(i2c_periph, I2C_FLAG_BTC));
104     }
105 
106     return 0;
107 }
108 
gd32_i2c_configure(struct gd32_i2c_config * i2c_cfg)109 static void gd32_i2c_configure(struct gd32_i2c_config *i2c_cfg)
110 {
111     RT_ASSERT(i2c_cfg != RT_NULL);
112 
113     /* configure i2c speed to 100Khz */
114     i2c_clock_config(i2c_cfg->i2c_periph, i2c_cfg->speed, I2C_DTCY_2);
115     /* enable I2C */
116     i2c_enable(i2c_cfg->i2c_periph);
117     /* enable acknowledge */
118     i2c_ack_config(i2c_cfg->i2c_periph, I2C_ACK_ENABLE);
119 }
120 
121 
gd32_i2c_xfer(struct rt_i2c_bus_device * device,struct rt_i2c_msg msgs[],rt_uint32_t num)122 static rt_ssize_t gd32_i2c_xfer(struct rt_i2c_bus_device *device, struct rt_i2c_msg msgs[], rt_uint32_t num)
123 {
124     struct rt_i2c_msg *msg;
125     rt_uint32_t i;
126     rt_err_t ret = -RT_ERROR;
127     rt_uint16_t last_flags;
128 
129     RT_ASSERT(device != RT_NULL);
130 
131     struct gd32_i2c *i2c_obj = (struct gd32_i2c *)(device);
132     struct gd32_i2c_config *i2c_cfg = (struct gd32_i2c_config *)(i2c_obj->config);
133     RT_ASSERT(i2c_cfg != RT_NULL);
134 
135     /* wait until I2C bus is idle */
136     while (i2c_flag_get(i2c_cfg->i2c_periph, I2C_FLAG_I2CBSY));
137 
138     if (num)
139     {
140         if (msg[0].flags & RT_I2C_ADDR_10BIT)
141         {
142             i2c_mode_addr_config(i2c_cfg->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_10BITS, 0x82);
143         }
144         else
145         {
146             i2c_mode_addr_config(i2c_cfg->i2c_periph, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x82);
147         }
148     }
149     for (i = 0; i < num; i++)
150     {
151         msg = &msgs[i];
152 
153         if (!(msg->flags & RT_I2C_NO_START))
154         {
155             /* send a start condition to I2C bus */
156             i2c_start_on_bus(i2c_cfg->i2c_periph);
157             /* wait until SBSEND bit is set */
158             while (!i2c_flag_get(i2c_cfg->i2c_periph, I2C_FLAG_SBSEND));
159         }
160 
161         if (msg->flags & RT_I2C_RD)
162         {
163             gd32_i2c_read(i2c_cfg->i2c_periph, msg->addr, msg->buf, msg->len);
164         }
165         else
166         {
167             gd32_i2c_write(i2c_cfg->i2c_periph, msg->addr, msg->buf, msg->len);
168         }
169     }
170 
171     if (num)
172     {
173         /* send a stop condition to I2C bus */
174         i2c_stop_on_bus(i2c_cfg->i2c_periph);
175 
176         /* wait until the stop condition is finished */
177         while (I2C_CTL0(i2c_cfg->i2c_periph) & I2C_CTL0_STOP);
178     }
179     i2c_ack_config(i2c_cfg->i2c_periph, I2C_ACK_ENABLE);
180 
181     ret = i;
182 
183     return ret;
184 }
185 
186 static const struct rt_i2c_bus_device_ops i2c_ops =
187 {
188     gd32_i2c_xfer,
189     RT_NULL,
190     RT_NULL
191 };
192 
rt_hw_i2c_init(void)193 int rt_hw_i2c_init(void)
194 {
195     rt_size_t obj_num;
196     int index;
197     rt_err_t result = 0;
198 
199 #ifdef BSP_USING_I2C0
200     rcu_periph_clock_enable(RCU_I2C0);
201 #endif
202 #ifdef BSP_USING_I2C1
203     rcu_periph_clock_enable(RCU_I2C1);
204 #endif
205 
206     obj_num = sizeof(i2c_obj) / sizeof(struct gd32_i2c);
207     for (index = 0; index < obj_num; index++)
208     {
209         /* init i2c object */
210         i2c_obj[index].config = &i2c_config[index];
211         i2c_obj[index].bus.ops = &i2c_ops;
212 
213         /* init i2c device */
214         gd32_i2c_configure(&i2c_config[index]);
215 
216         /* register i2c device */
217         result = rt_i2c_bus_device_register(&i2c_obj[index].bus,
218                                             i2c_obj[index].config->name
219                                            );
220         RT_ASSERT(result == RT_EOK);
221     }
222 
223     return 0;
224 }
225 INIT_DEVICE_EXPORT(rt_hw_i2c_init);
226 
227 #endif
228 /* end of i2c driver */
229