1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: Provides V150 i2c common function. \n
16 *
17 * History: \n
18 * 2023-03-06, Create file. \n
19 */
20
21 #include "common_def.h"
22 #include "hal_i2c.h"
23 #include "hal_i2c_v150_regs_op.h"
24 #include "hal_i2c_v150_comm.h"
25
26
27 // 当前的传输信息,包含传输模式、已传输数据长度,剩余数据长度
28 static hal_i2c_trans_info_t g_hal_i2c_trans_info[I2C_BUS_MAX_NUM] = {
29 #if I2C_BUS_MAX_NUM > 1
30 {I2C_TRANS_MODE_INVALID, 0, I2C_V150_DEFAULT_WRITE_NUM},
31 #if I2C_BUS_MAX_NUM > 2
32 {I2C_TRANS_MODE_INVALID, 0, I2C_V150_DEFAULT_WRITE_NUM},
33 #if I2C_BUS_MAX_NUM > 3
34 {I2C_TRANS_MODE_INVALID, 0, I2C_V150_DEFAULT_WRITE_NUM},
35 #endif
36 #endif
37 #endif
38 {I2C_TRANS_MODE_INVALID, 0, I2C_V150_DEFAULT_WRITE_NUM}
39 };
40
41 /* I2C控制函数表 */
42 static hal_i2c_inner_ctrl_t *g_hal_i2c_ctrl_func[I2C_BUS_MAX_NUM];
43
44 /* I2C控制信息 */
45 static hal_i2c_ctrl_info_t g_hal_i2c_ctrl_info[I2C_BUS_MAX_NUM] = {
46 #if I2C_BUS_MAX_NUM > 1
47 {I2C_FALSE, I2C_CFG_SCL_H_DEFAULT_VAL, I2C_CFG_SCL_L_DEFAULT_VAL, I2C_WORK_TYPE_POLL_NOFIFO,
48 CONFIG_I2C_WAIT_CONDITION_TIMEOUT, I2C_SS_MODE_BAUDRATE_HIGH_LIMIT, NULL},
49 #if I2C_BUS_MAX_NUM > 2
50 {I2C_FALSE, I2C_CFG_SCL_H_DEFAULT_VAL, I2C_CFG_SCL_L_DEFAULT_VAL, I2C_WORK_TYPE_POLL_NOFIFO,
51 CONFIG_I2C_WAIT_CONDITION_TIMEOUT, I2C_SS_MODE_BAUDRATE_HIGH_LIMIT, NULL},
52 #if I2C_BUS_MAX_NUM > 3
53 {I2C_FALSE, I2C_CFG_SCL_H_DEFAULT_VAL, I2C_CFG_SCL_L_DEFAULT_VAL, I2C_WORK_TYPE_POLL_NOFIFO,
54 CONFIG_I2C_WAIT_CONDITION_TIMEOUT, I2C_SS_MODE_BAUDRATE_HIGH_LIMIT, NULL},
55 #endif
56 #endif
57 #endif
58 {I2C_FALSE, I2C_CFG_SCL_H_DEFAULT_VAL, I2C_CFG_SCL_L_DEFAULT_VAL, I2C_WORK_TYPE_POLL_NOFIFO,
59 CONFIG_I2C_WAIT_CONDITION_TIMEOUT, I2C_SS_MODE_BAUDRATE_HIGH_LIMIT, NULL}
60 };
61
62 /* I2C中断处理回调 */
63 hal_i2c_callback_t g_hal_i2c_callback = NULL;
64
65 /* 获取控制信息 */
hal_i2c_v150_get_ctrl_info(i2c_bus_t bus)66 hal_i2c_ctrl_info_t *hal_i2c_v150_get_ctrl_info(i2c_bus_t bus)
67 {
68 return &g_hal_i2c_ctrl_info[bus];
69 }
70
71 /* 加载控制函数表 */
hal_i2c_v150_load_ctrl_func(i2c_bus_t bus,hal_i2c_inner_ctrl_t * func_table)72 void hal_i2c_v150_load_ctrl_func(i2c_bus_t bus, hal_i2c_inner_ctrl_t *func_table)
73 {
74 g_hal_i2c_ctrl_func[bus] = func_table;
75 }
76
77 /* 卸载控制函数表 */
hal_i2c_v150_unload_ctrl_func(i2c_bus_t bus)78 void hal_i2c_v150_unload_ctrl_func(i2c_bus_t bus)
79 {
80 g_hal_i2c_ctrl_func[bus] = NULL;
81 }
82
83 /* 加载中断处理回调 */
hal_i2c_v150_register_callback(hal_i2c_callback_t callback)84 void hal_i2c_v150_register_callback(hal_i2c_callback_t callback)
85 {
86 g_hal_i2c_callback = callback;
87 }
88
89 /* 获取传输信息 */
hal_i2c_v150_get_trans_info(i2c_bus_t bus)90 hal_i2c_trans_info_t *hal_i2c_v150_get_trans_info(i2c_bus_t bus)
91 {
92 return &g_hal_i2c_trans_info[bus];
93 }
94
95 /* 框架适配用函数, 入参指针写入True */
hal_i2c_v150_ctrl_check_default(i2c_bus_t bus,uintptr_t param)96 errcode_t hal_i2c_v150_ctrl_check_default(i2c_bus_t bus, uintptr_t param)
97 {
98 unused(bus);
99 *(uint32_t *)param = I2C_TRUE;
100 return ERRCODE_SUCC;
101 }
102
103 /* 框架适配用函数, 入参指针写入False */
hal_i2c_v150_ctrl_check_default_false(i2c_bus_t bus,uintptr_t param)104 errcode_t hal_i2c_v150_ctrl_check_default_false(i2c_bus_t bus, uintptr_t param)
105 {
106 unused(bus);
107 *(uint32_t *)param = I2C_FALSE;
108 return ERRCODE_SUCC;
109 }
110
111 /* 框架适配用函数, 不处理参数 */
hal_i2c_v150_ctrl_proc_default(i2c_bus_t bus,uintptr_t param)112 errcode_t hal_i2c_v150_ctrl_proc_default(i2c_bus_t bus, uintptr_t param)
113 {
114 unused(bus);
115 unused(param);
116 return ERRCODE_SUCC;
117 }
118
119 /* 获取可发送字节数, 不使用FIFO默认全部发送 */
hal_i2c_v150_get_write_num(i2c_bus_t bus,uintptr_t param)120 errcode_t hal_i2c_v150_get_write_num(i2c_bus_t bus, uintptr_t param)
121 {
122 unused(bus);
123 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
124 *(uint32_t *)param = 1; // 中断模式,每次写一个字节
125 #else
126 *(uint32_t *)param = I2C_V150_DEFAULT_WRITE_NUM;
127 #endif
128 return ERRCODE_SUCC;
129 }
130
131 /* 获取可读取字节数, 不使用FIFO默认全部读取 */
hal_i2c_v150_get_read_num(i2c_bus_t bus,uintptr_t param)132 errcode_t hal_i2c_v150_get_read_num(i2c_bus_t bus, uintptr_t param)
133 {
134 unused(bus);
135 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
136 *(uint32_t *)param = 1; // 中断模式,每次读一个字节
137 #else
138 *(uint32_t *)param = I2C_V150_DEFAULT_READ_NUM;
139 #endif
140 return ERRCODE_SUCC;
141 }
142
143 #if !(defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1))
144 /* 进行操作后等待 I2C_INT_DONE 完成中断上报 */
hal_i2c_v150_wait(i2c_bus_t bus)145 static errcode_t hal_i2c_v150_wait(i2c_bus_t bus)
146 {
147 uint32_t int_state;
148 uint32_t time_out = 0;
149
150 hal_i2c_ctrl_info_t *hal_i2c_ctrl_info = hal_i2c_v150_get_ctrl_info(bus);
151 int_state = hal_i2c_v150_get_int_state(bus);
152 while (((int_state & I2C_INT_TYPE_DONE) != I2C_INT_TYPE_DONE) && (time_out < hal_i2c_ctrl_info->timeout_us)) {
153 time_out++;
154 int_state = hal_i2c_v150_get_int_state(bus);
155 osal_udelay(1);
156 }
157 if (time_out >= hal_i2c_ctrl_info->timeout_us) {
158 hal_i2c_v150_clear_all_int(bus);
159 return ERRCODE_I2C_TIMEOUT;
160 }
161
162 if (int_state & I2C_INT_TYPE_ACK_ERR) {
163 hal_i2c_v150_clear_all_int(bus);
164 return ERRCODE_I2C_ACK_ERR;
165 }
166 return ERRCODE_SUCC;
167 }
168
169 /* 发送停止信号, 并等待操作完成 */
hal_i2c_v150_stop(i2c_bus_t bus)170 static errcode_t hal_i2c_v150_stop(i2c_bus_t bus)
171 {
172 uint32_t ret;
173
174 hal_i2c_v150_set_command(bus, I2C_OP_STOP);
175
176 ret = hal_i2c_v150_wait(bus);
177 if (ret != ERRCODE_SUCC) {
178 return ret;
179 }
180
181 hal_i2c_v150_clear_all_int(bus);
182
183 return ERRCODE_SUCC;
184 }
185 #endif
186
187 /* 发送一个字节 */
hal_i2c_v150_send_byte(i2c_bus_t bus,uint8_t data,uint8_t should_start)188 errcode_t hal_i2c_v150_send_byte(i2c_bus_t bus, uint8_t data, uint8_t should_start)
189 {
190 // 发送字节
191 hal_i2c_v150_set_tx_data(bus, data);
192 hal_i2c_v150_set_command(bus, ((should_start ? I2C_OP_START : 0) | I2C_OP_WRITE));
193
194 #if !(defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1))
195 uint32_t ret;
196 // 等待中断状态
197 ret = hal_i2c_v150_wait(bus);
198 if (ret != ERRCODE_SUCC) {
199 return ret;
200 }
201
202 // 清除中断状态
203 hal_i2c_v150_clear_int(bus, ((should_start ? I2C_INT_TYPE_START : 0) | I2C_INT_TYPE_TX | I2C_INT_TYPE_DONE));
204 #endif /* CONFIG_I2C_SUPPORT_INT */
205
206 return ERRCODE_SUCC;
207 }
208
209 /* 接收一个字节 */
hal_i2c_v150_receive_byte(i2c_bus_t bus,uint8_t * data,uint32_t remain_len)210 errcode_t hal_i2c_v150_receive_byte(i2c_bus_t bus, uint8_t *data, uint32_t remain_len)
211 {
212 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
213 if (remain_len == 2) { // 中断模式2表示即将收最后一个数据
214 hal_i2c_v150_disable_ack(bus);
215 }
216 // 读取接收字节
217 *data = hal_i2c_v150_get_rx_data(bus);
218 if (remain_len > 1) {
219 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_READ;
220 hal_i2c_v150_set_command(bus, I2C_OP_READ);
221 }
222
223 // 最后一个字节结束后, 恢复ACK设置
224 if (remain_len == 1) {
225 hal_i2c_v150_enable_ack(bus);
226 }
227 #else
228 uint32_t ret;
229 // 最后一个字节不发送ACK, 代表读取结束
230 if (remain_len == 1) {
231 hal_i2c_v150_disable_ack(bus);
232 }
233
234 // 接收字节
235 hal_i2c_v150_set_command(bus, I2C_OP_READ);
236 // 等待中断状态
237 ret = hal_i2c_v150_wait(bus);
238 if (ret != ERRCODE_SUCC) {
239 return ret;
240 }
241 // 读取接收字节
242 *data = hal_i2c_v150_get_rx_data(bus);
243 // 清除中断状态
244 hal_i2c_v150_clear_int(bus, (I2C_INT_TYPE_RX | I2C_INT_TYPE_DONE));
245
246 // 最后一个字节结束后, 恢复ACK设置
247 if (remain_len == 1) {
248 hal_i2c_v150_enable_ack(bus);
249 }
250 #endif /* CONFIG_I2C_SUPPORT_INT */
251 return ERRCODE_SUCC;
252 }
253
254 /* 循环发送, 每次发送一个字节 */
255 #pragma weak hal_i2c_write = hal_i2c_v150_write
hal_i2c_v150_write(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data)256 errcode_t hal_i2c_v150_write(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data)
257 {
258 if (data->len == 0) {
259 return ERRCODE_I2C_SEND_PARAM_INVALID;
260 }
261
262 uint8_t should_start;
263 uint32_t ret;
264
265 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
266 should_start = (data->restart_flag && (g_hal_i2c_trans_info[bus].trans_cnt == 0)) ? I2C_TRUE : I2C_FALSE;
267 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_WRITE;
268 (g_hal_i2c_trans_info[bus].trans_cnt)++;
269 ret = hal_i2c_v150_send_byte(bus, data->buffer[0], should_start);
270 if (ret != ERRCODE_SUCC) {
271 return ret;
272 }
273 #else
274 uint32_t byte_cnt;
275 for (byte_cnt = 0; byte_cnt < data->len; byte_cnt++) {
276 // restart_flag置位时, 在首个字节发送时产生start信号
277 should_start = (data->restart_flag && (byte_cnt == 0)) ? I2C_TRUE : I2C_FALSE;
278
279 // 发送字节
280 ret = hal_i2c_v150_send_byte(bus, data->buffer[byte_cnt], should_start);
281 if (ret != ERRCODE_SUCC) {
282 return ret;
283 }
284 }
285 // 发送完成后检查是否需要产生stop信号
286 if (data->stop_flag) {
287 ret = hal_i2c_v150_stop(bus);
288 if (ret != ERRCODE_SUCC) {
289 return ret;
290 }
291 }
292 #endif /* CONFIG_I2C_SUPPORT_INT */
293 return ERRCODE_SUCC;
294 }
295
296 /* 循环读取, 每次读取一个字节 */
297 #pragma weak hal_i2c_read = hal_i2c_v150_read
hal_i2c_v150_read(i2c_bus_t bus,hal_i2c_buffer_wrap_t * data)298 errcode_t hal_i2c_v150_read(i2c_bus_t bus, hal_i2c_buffer_wrap_t *data)
299 {
300 // 不使用FIFO模式, 默认读一个字节
301 if (data->len == 0) {
302 return ERRCODE_I2C_RECEIVE_PARAM_INVALID;
303 }
304
305 uint32_t ret;
306 uint32_t remain_len;
307 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
308 remain_len = g_hal_i2c_trans_info[bus].total_len - g_hal_i2c_trans_info[bus].trans_cnt;
309 (g_hal_i2c_trans_info[bus].trans_cnt)++;
310 ret = hal_i2c_v150_receive_byte(bus, &(data->buffer[0]), remain_len);
311 if (ret != ERRCODE_SUCC) {
312 return ret;
313 }
314 #else
315 uint32_t byte_cnt;
316 for (byte_cnt = 0; byte_cnt < data->len; byte_cnt++) {
317 remain_len = data->len - byte_cnt;
318 // 接收字节
319 ret = hal_i2c_v150_receive_byte(bus, &(data->buffer[byte_cnt]), remain_len);
320 if (ret != ERRCODE_SUCC) {
321 return ret;
322 }
323 }
324 // 读取完成后默认产生stop信号
325 ret = hal_i2c_v150_stop(bus);
326 if (ret != ERRCODE_SUCC) {
327 return ret;
328 }
329 #endif /* CONFIG_I2C_SUPPORT_INT */
330 return ERRCODE_SUCC;
331 }
332
333 /* i2c去初始化 */
334 #pragma weak hal_i2c_deinit = hal_i2c_v150_deinit
hal_i2c_v150_deinit(i2c_bus_t bus)335 errcode_t hal_i2c_v150_deinit(i2c_bus_t bus)
336 {
337 hal_i2c_ctrl_info_t *hal_i2c_ctrl_info = hal_i2c_v150_get_ctrl_info(bus);
338 if (!hal_i2c_ctrl_info->init) {
339 return ERRCODE_I2C_NOT_INIT;
340 }
341
342 hal_i2c_ctrl_info->init = I2C_FALSE;
343
344 hal_i2c_v150_set_i2c_disable(bus);
345 hal_i2c_v150_mask_main_int(bus);
346 hal_i2c_v150_mask_all_int(bus);
347 hal_i2c_v150_clear_all_int(bus);
348 hal_i2c_v150_unload_ctrl_func(bus);
349 hal_i2c_v150_regs_deinit(bus);
350
351 return ERRCODE_SUCC;
352 }
353
hal_i2c_v150_cfg_clk(i2c_bus_t bus,uint32_t baudrate,uint8_t scl_h,uint8_t scl_l)354 void hal_i2c_v150_cfg_clk(i2c_bus_t bus, uint32_t baudrate, uint8_t scl_h, uint8_t scl_l)
355 {
356 uint16_t clk_val;
357 uint32_t i2c_clk = i2c_port_get_clock_value(bus);
358
359 hal_i2c_v150_mask_main_int(bus);
360
361 clk_val = (i2c_clk / (baudrate * 2)) * scl_h / (scl_l + scl_h) - 1; // 计算时波特率乘2
362 hal_i2c_v150_set_scl_h(bus, clk_val);
363 clk_val = (i2c_clk / (baudrate * 2)) * scl_l / (scl_l + scl_h) - 1; // 计算时波特率乘2
364 hal_i2c_v150_set_scl_l(bus, clk_val);
365
366 hal_i2c_v150_unmask_main_int(bus);
367 }
368
369 /* 初始化配置控制参数 */
hal_i2c_v150_init_comp_param(i2c_bus_t bus)370 void hal_i2c_v150_init_comp_param(i2c_bus_t bus)
371 {
372 hal_i2c_ctrl_info_t *hal_i2c_ctrl_info = &g_hal_i2c_ctrl_info[bus];
373 hal_i2c_ctrl_info->init = I2C_FALSE;
374 hal_i2c_ctrl_info->cfg_scl_h = I2C_CFG_SCL_H_DEFAULT_VAL;
375 hal_i2c_ctrl_info->cfg_scl_l = I2C_CFG_SCL_L_DEFAULT_VAL;
376 hal_i2c_ctrl_info->work_type = I2C_WORK_TYPE_POLL_NOFIFO;
377 hal_i2c_ctrl_info->timeout_us = CONFIG_I2C_WAIT_CONDITION_TIMEOUT;
378 hal_i2c_ctrl_info->baudrate = I2C_SS_MODE_BAUDRATE_HIGH_LIMIT;
379 hal_i2c_ctrl_info->ext = NULL;
380 }
381
382 #pragma weak hal_i2c_ctrl = hal_i2c_v150_ctrl
hal_i2c_v150_ctrl(i2c_bus_t bus,hal_i2c_ctrl_id_t id,uintptr_t param)383 errcode_t hal_i2c_v150_ctrl(i2c_bus_t bus, hal_i2c_ctrl_id_t id, uintptr_t param)
384 {
385 if (g_hal_i2c_ctrl_func[bus] == NULL) {
386 return ERRCODE_I2C_NOT_INIT;
387 }
388 if (g_hal_i2c_ctrl_func[bus][id] != NULL) {
389 return g_hal_i2c_ctrl_func[bus][id](bus, param);
390 }
391 return ERRCODE_I2C_NOT_IMPLEMENT;
392 }
393
394 /* 中断回调函数 */
hal_i2c_v150_irq_handler(i2c_bus_t bus)395 void hal_i2c_v150_irq_handler(i2c_bus_t bus)
396 {
397 unused(bus);
398 if (!g_hal_i2c_callback) {
399 return;
400 }
401 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
402 volatile i2c_sr_data_t i2c_int_reg = (i2c_sr_data_t)g_i2c_regs[bus]->i2c_sr;
403 g_i2c_regs[bus]->i2c_icr = i2c_int_reg.d32; // 清除已产生中断
404
405 if ((i2c_int_reg.d32 & I2C_INT_TYPE_DONE) == I2C_INT_TYPE_DONE) {
406 if (g_hal_i2c_trans_info[bus].trans_mode == I2C_TRANS_MODE_WRITE_BEFORE_READ) {
407 // 触发rx 读数据,只有一个字节时需要发disable ack?
408 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_READ;
409 if (g_hal_i2c_trans_info[bus].total_len == 1) {
410 hal_i2c_v150_disable_ack(bus);
411 }
412 hal_i2c_v150_set_command(bus, I2C_OP_READ);
413 } else if (g_hal_i2c_trans_info[bus].trans_mode == I2C_TRANS_MODE_WRITE) {
414 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_INVALID;
415 g_hal_i2c_callback(bus, I2C_EVT_TX_READY, NULL);
416 } else if (g_hal_i2c_trans_info[bus].trans_mode == I2C_TRANS_MODE_READ) {
417 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_INVALID;
418 g_hal_i2c_callback(bus, I2C_EVT_RX_READY, NULL);
419 }
420 }
421
422 if ((i2c_int_reg.d32 & I2C_INT_TYPE_STOP) == I2C_INT_TYPE_STOP &&
423 g_hal_i2c_trans_info[bus].trans_mode == I2C_TRANS_MODE_STOP_AFTER_WRITE) {
424 g_hal_i2c_trans_info[bus].trans_mode = I2C_TRANS_MODE_INVALID;
425 g_hal_i2c_callback(bus, I2C_EVT_TRANSMITION_DONE, NULL);
426 }
427
428 if (hal_i2c_v150_is_bus_busy(bus) == 1) {
429 g_hal_i2c_callback(bus, I2C_EVT_TRANSMITION_BUSY, NULL);
430 }
431 if ((i2c_int_reg.d32 & I2C_INT_TYPE_ACK_ERR) == I2C_INT_TYPE_ACK_ERR) {
432 g_hal_i2c_callback(bus, I2C_EVT_TRANSMITION_ABRT, NULL);
433 }
434 #endif
435 }