• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }