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-4-1 IceBear003 the first version
9 */
10
11 #include "board.h"
12 #include "drv_i2c.h"
13
14 #ifdef BSP_USING_HWI2C
15
16 #define LOG_TAG "drv.hwi2c"
17 #include "drv_log.h"
18
19 #if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2)
20 #error "Please define at least one BSP_USING_I2Cx"
21 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
22 #endif
23
24 #define TIMEOUT 0xFF
25
26 #ifdef BSP_USING_I2C1
27 struct i2c_bus_device i2c_bus1;
28 #endif
29 #ifdef BSP_USING_I2C2
30 struct i2c_bus_device i2c_bus2;
31 #endif
32
i2c_read(I2C_TypeDef * i2c_periph,rt_uint16_t addr,rt_uint8_t flags,rt_uint16_t len,rt_uint8_t * buf)33 static int i2c_read(I2C_TypeDef *i2c_periph,
34 rt_uint16_t addr,
35 rt_uint8_t flags,
36 rt_uint16_t len,
37 rt_uint8_t *buf)
38 {
39 rt_uint16_t try = 0;
40 while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
41 if (try++ >= TIMEOUT) return -1;
42
43 I2C_GenerateSTART(i2c_periph, ENABLE);
44
45 try = 0;
46 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
47 if (try++ >= TIMEOUT) return -1;
48
49 if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
50 {
51 rt_uint8_t frame_head = 0xF0 + (addr >> 8) << 1; //11110XX0
52 I2C_SendData(i2c_periph, frame_head); //FrameHead
53
54 try = 0;
55 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
56 if (try++ >= TIMEOUT) return -1;
57
58 I2C_SendData(i2c_periph,0xff & addr);
59
60 try = 0;
61 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
62 if (try++ >= TIMEOUT) return -1;
63
64 I2C_GenerateSTART(i2c_periph, ENABLE); //Sr
65
66 try = 0;
67 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
68 if (try++ >= TIMEOUT) return -1;
69
70 I2C_SendData(i2c_periph,frame_head); //Resend FrameHead
71 }
72 else
73 {
74 I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Receiver);
75 }
76
77 try = 0;
78 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //EVT6
79 if (try++ >= TIMEOUT) return -1;
80
81 while(len-- > 0)
82 {
83
84 try = 0;
85 while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE)) //Got ACK For the Last Byte
86 if (try++ >= TIMEOUT) return -1;
87
88 *(buf++)=I2C_ReceiveData(i2c_periph);
89 }
90
91 I2C_GenerateSTOP(i2c_periph, ENABLE);
92 }
93
i2c_write(I2C_TypeDef * i2c_periph,rt_uint16_t addr,rt_uint8_t flags,rt_uint8_t * buf,rt_uint16_t len)94 static int i2c_write(I2C_TypeDef *i2c_periph,
95 rt_uint16_t addr,
96 rt_uint8_t flags,
97 rt_uint8_t *buf,
98 rt_uint16_t len)
99 {
100 rt_uint16_t try = 0;
101 while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
102 if (try++ >= TIMEOUT) return -1;
103
104 I2C_GenerateSTART(i2c_periph, ENABLE);
105
106 try = 0;
107 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
108 if (try++ >= TIMEOUT) return -1;
109
110 if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
111 {
112 I2C_SendData(i2c_periph,0xF0 + (addr >> 8) << 1); //FrameHead 11110XX0
113
114 try = 0;
115 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
116 if (try++ >= TIMEOUT) return -1;
117
118 I2C_SendData(i2c_periph,0xff & addr);
119 }
120 else //7-bit address mode
121 {
122 I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Transmitter);
123 }
124
125 try = 0;
126 while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
127 if (try++ >= TIMEOUT) return -1;
128
129 //Missing Evt8_1 (No definition)
130
131 while(len-- > 0)
132 {
133 try = 0;
134 while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_TXE)) //Got ACK For the Last Byte
135 if (try++ >= TIMEOUT) return -1;
136
137 I2C_SendData(i2c_periph,*(buf++));
138 }
139
140 try = 0;
141 while(!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //Last byte sent successfully
142 if (try++ >= TIMEOUT) return -1;
143
144 I2C_GenerateSTOP(i2c_periph, ENABLE);
145 }
146
i2c_master_xfer(struct rt_i2c_bus_device * bus,struct rt_i2c_msg msgs[],rt_uint32_t num)147 rt_size_t i2c_master_xfer(struct rt_i2c_bus_device *bus,
148 struct rt_i2c_msg msgs[],
149 rt_uint32_t num)
150 {
151 struct rt_i2c_msg *msg;
152 struct i2c_bus_device *i2c_bus_dev;
153 rt_uint32_t index;
154
155 i2c_bus_dev = (struct i2c_bus_device *)bus;
156
157 for (index = 0; index < num; index++)
158 {
159 msg = &msgs[index];
160 if (msg->flags & RT_I2C_RD)
161 {
162 i2c_read(i2c_bus_dev->periph,
163 msg->addr,
164 msg->flags,
165 msg->len,
166 msg->buf);
167 }
168 else
169 {
170 i2c_write(i2c_bus_dev->periph,
171 msg->addr,
172 msg->flags,
173 msg->buf,
174 msg->len);
175 }
176 }
177
178 return index;
179 }
180
181 static const struct rt_i2c_bus_device_ops ch32_i2c_ops =
182 {
183 .master_xfer = i2c_master_xfer,
184 .slave_xfer = RT_NULL, //Not Used in i2c_core?
185 .i2c_bus_control = RT_NULL
186 };
187
188 int rt_hw_i2c_init(struct i2c_config *config = &{5000, I2C_DutyCycle_2, 0, I2C_Ack_Disable, I2C_AcknowledgedAddress_7bit})
189 {
190 int result = RT_EOK;
191
192 GPIO_InitTypeDef GPIO_InitStructure = {0};
193 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
194 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
195
196 I2C_InitTypeDef I2C_InitTSturcture = {0};
197 I2C_StructInit(&I2C_InitTSturcture);
198 I2C_InitTSturcture.I2C_ClockSpeed = config->clock_speed;
199 I2C_InitTSturcture.I2C_DutyCycle = config->duty_cycle;
200 I2C_InitTSturcture.I2C_OwnAddress1 = config->own_address;
201 I2C_InitTSturcture.I2C_Ack = config->enable_ack ? I2C_Ack_Enable : I2C_Ack_Disable;
202 I2C_InitTSturcture.I2C_AcknowledgedAddress = config->is_7_bit_address ? I2C_AcknowledgedAddress_7bit : I2C_AcknowledgedAddress_10bit;
203
204
205 #ifdef BSP_USING_I2C1
206
207 i2c_bus1.periph = I2C1;
208
209 //Clock & IO Initialization
210 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
211 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
212
213 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
214 GPIO_Init(GPIOB, &GPIO_InitStructure);
215
216 GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
217
218 //I2C Initialization Config
219 I2C_Init(I2C1, &I2C_InitTSturcture);
220 I2C_Cmd(I2C1, ENABLE);
221
222 //Hook to RT-Thread
223 i2c_bus1.parent.ops = &ch32_i2c_ops;
224 result += rt_i2c_bus_device_register(&i2c_bus1.parent, "i2c1");
225
226 #endif
227
228 #ifdef BSP_USING_I2C2
229
230 i2c_bus2.periph = I2C2;
231
232 //Clock & IO Initialization
233 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
234 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
235
236 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
237 GPIO_Init(GPIOB, &GPIO_InitStructure);
238
239 //I2C Initialization Config
240 I2C_Init(I2C2, &I2C_InitTSturcture);
241 I2C_Cmd(I2C2, ENABLE);
242
243 //Hook to RT-Thread
244 i2c_bus2.parent.ops = &ch32_i2c_ops;
245 result += rt_i2c_bus_device_register(&i2c_bus2.parent, "i2c2");
246
247 #endif
248
249 return result;
250 }
251
252 #endif //BSP_USING_HWI2C