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 HAL i2c \n
16 *
17 * History: \n
18 * 2023-03-06, Create file. \n
19 */
20
21 #include <stdint.h>
22 #include "securec.h"
23 #include "common_def.h"
24 #include "i2c_porting.h"
25 #include "hal_i2c.h"
26 #include "hal_i2c_v150_comm.h"
27 #include "hal_i2c_v150_master.h"
28
hal_i2c_v150_get_speed_mode(uint32_t baudrate)29 static hal_i2c_speed_mode_t hal_i2c_v150_get_speed_mode(uint32_t baudrate)
30 {
31 if (baudrate <= I2C_SS_MODE_BAUDRATE_HIGH_LIMIT) {
32 return I2C_SPEED_MODE_SS;
33 } else if (baudrate <= I2C_FS_MODE_BAUDRATE_HIGH_LIMIT) {
34 return I2C_SPEED_MODE_FS;
35 }
36 return I2C_SPEED_MODE_HS;
37 }
38
hal_i2c_v150_master_get_addr_type(uint16_t addr)39 static uint8_t hal_i2c_v150_master_get_addr_type(uint16_t addr)
40 {
41 if ((addr | I2C_7BIT_ADDR_MASK) == I2C_7BIT_ADDR_MASK) {
42 return I2C_ADDR_TYPE_7BIT;
43 } else if ((addr | I2C_10BIT_ADDR_MASK) == I2C_10BIT_ADDR_MASK) {
44 return I2C_ADDR_TYPE_10BIT;
45 } else {
46 return I2C_ADDR_TYPE_INVALID;
47 }
48 }
49
50 /* 发送7bit地址 */
hal_i2c_v150_master_send_7bit_addr(i2c_bus_t bus,uint16_t addr,uint8_t is_write)51 static errcode_t hal_i2c_v150_master_send_7bit_addr(i2c_bus_t bus, uint16_t addr, uint8_t is_write)
52 {
53 uint8_t addr_byte = ((addr & I2C_7BIT_ADDR_MASK) << 1) & I2C_ADDR_WRITE_TAG;
54 if (is_write) {
55 addr_byte &= I2C_ADDR_WRITE_TAG;
56 } else {
57 addr_byte |= I2C_ADDR_READ_TAG;
58 }
59 return hal_i2c_v150_send_byte(bus, addr_byte, I2C_TRUE);
60 }
61
62 /* 发送10bit地址 */
hal_i2c_v150_master_send_10bit_addr(i2c_bus_t bus,uint16_t addr,uint8_t is_write)63 static errcode_t hal_i2c_v150_master_send_10bit_addr(i2c_bus_t bus, uint16_t addr, uint8_t is_write)
64 {
65 uint8_t addr_byte_h = ((addr & I2C_10BIT_ADDR_MASK_H) >> I2C_10BIT_ADDR_MASK_H_OFFSET) | I2C_10BIT_ADDR_MASK_H_TAG;
66 uint8_t addr_byte_l = (addr & I2C_10BIT_ADDR_MASK_L) >> I2C_10BIT_ADDR_MASK_L_OFFSET;
67 uint32_t ret;
68
69 if (is_write) {
70 addr_byte_h &= I2C_ADDR_WRITE_TAG;
71 } else {
72 addr_byte_h |= I2C_ADDR_READ_TAG;
73 }
74
75 ret = hal_i2c_v150_send_byte(bus, addr_byte_h, I2C_TRUE);
76 if (ret != ERRCODE_SUCC) {
77 return ret;
78 }
79
80 return hal_i2c_v150_send_byte(bus, addr_byte_l, I2C_FALSE);
81 }
82
83 /* 配置目标器件地址 */
hal_i2c_v150_master_cfg_target_addr(i2c_bus_t bus,uint16_t addr,uint8_t is_write)84 static errcode_t hal_i2c_v150_master_cfg_target_addr(i2c_bus_t bus, uint16_t addr, uint8_t is_write)
85 {
86 uint32_t ret;
87 uint8_t addr_type = hal_i2c_v150_master_get_addr_type(addr);
88 if (addr_type == I2C_ADDR_TYPE_7BIT) {
89 ret = hal_i2c_v150_master_send_7bit_addr(bus, addr, is_write);
90 if (ret != ERRCODE_SUCC) {
91 return ret;
92 }
93 } else if (addr_type == I2C_ADDR_TYPE_10BIT) {
94 ret = hal_i2c_v150_master_send_10bit_addr(bus, addr, is_write);
95 if (ret != ERRCODE_SUCC) {
96 return ret;
97 }
98 } else {
99 return ERRCODE_I2C_ADDRESS_INVLID;
100 }
101
102 return ERRCODE_SUCC;
103 }
104
hal_i2c_v150_master_operate_prepare(i2c_bus_t bus)105 static errcode_t hal_i2c_v150_master_operate_prepare(i2c_bus_t bus)
106 {
107 hal_i2c_ctrl_info_t *hal_i2c_ctrl_info = hal_i2c_v150_get_ctrl_info(bus);
108
109 /* 锁上后再次检查init标志 */
110 if (!hal_i2c_ctrl_info->init) {
111 return ERRCODE_I2C_NOT_INIT;
112 }
113 return ERRCODE_SUCC;
114 }
115
116 /* 写操作前准备处理 */
hal_i2c_v150_master_write_prepeare(i2c_bus_t bus,uintptr_t param)117 static errcode_t hal_i2c_v150_master_write_prepeare(i2c_bus_t bus, uintptr_t param)
118 {
119 uint32_t ret;
120 hal_i2c_prepare_config_t *cfg = (hal_i2c_prepare_config_t *)param;
121
122 ret = hal_i2c_v150_master_operate_prepare(bus);
123 if (ret != ERRCODE_SUCC) {
124 return ret;
125 }
126 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
127 hal_i2c_trans_info_t *hal_i2c_trans_info = hal_i2c_v150_get_trans_info(bus);
128 hal_i2c_trans_info->trans_cnt = 0;
129 hal_i2c_trans_info->total_len = cfg->total_len;
130 hal_i2c_trans_info->trans_mode = I2C_TRANS_MODE_WRITE;
131 #endif
132 ret = hal_i2c_v150_master_cfg_target_addr(bus, cfg->addr, I2C_TRUE);
133 if (ret != ERRCODE_SUCC) {
134 return ret;
135 }
136 hal_i2c_v150_clear_all_int(bus);
137
138 return ERRCODE_SUCC;
139 }
140
141 /* 写操作后恢复处理 */
hal_i2c_v150_master_write_restore(i2c_bus_t bus,uintptr_t param)142 static errcode_t hal_i2c_v150_master_write_restore(i2c_bus_t bus, uintptr_t param)
143 {
144 unused(param);
145 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
146 hal_i2c_trans_info_t *hal_i2c_trans_info = hal_i2c_v150_get_trans_info(bus);
147 hal_i2c_trans_info->trans_mode = I2C_TRANS_MODE_STOP_AFTER_WRITE;
148 hal_i2c_v150_set_command(bus, I2C_OP_STOP);
149 #endif
150 hal_i2c_v150_clear_all_int(bus);
151 return ERRCODE_SUCC;
152 }
153
154 /* 读操作前准备处理 */
hal_i2c_v150_master_read_prepeare(i2c_bus_t bus,uintptr_t param)155 static errcode_t hal_i2c_v150_master_read_prepeare(i2c_bus_t bus, uintptr_t param)
156 {
157 uint32_t ret;
158 hal_i2c_prepare_config_t *cfg = (hal_i2c_prepare_config_t *)param;
159
160 ret = hal_i2c_v150_master_operate_prepare(bus);
161 if (ret != ERRCODE_SUCC) {
162 return ret;
163 }
164 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
165 hal_i2c_trans_info_t *hal_i2c_trans_info = hal_i2c_v150_get_trans_info(bus);
166 hal_i2c_trans_info->trans_cnt = 0;
167 hal_i2c_trans_info->total_len = cfg->total_len;
168 hal_i2c_trans_info->trans_mode = I2C_TRANS_MODE_WRITE_BEFORE_READ;
169 #endif
170 ret = hal_i2c_v150_master_cfg_target_addr(bus, cfg->addr, I2C_FALSE);
171 if (ret != ERRCODE_SUCC) {
172 return ret;
173 }
174 hal_i2c_v150_clear_all_int(bus);
175
176 return ERRCODE_SUCC;
177 }
178
179 /* 读操作后恢复处理 */
hal_i2c_v150_master_read_restore(i2c_bus_t bus,uintptr_t param)180 static errcode_t hal_i2c_v150_master_read_restore(i2c_bus_t bus, uintptr_t param)
181 {
182 unused(param);
183 #if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1)
184 hal_i2c_v150_set_command(bus, I2C_OP_STOP);
185 #endif
186 hal_i2c_v150_clear_all_int(bus);
187 return ERRCODE_SUCC;
188 }
189
190 static hal_i2c_inner_ctrl_t g_hal_i2c_master_ctrl_func_array[I2C_CTRL_MAX] = {
191 hal_i2c_v150_master_write_prepeare, /* I2C_CTRL_WRITE_PREPARE */
192 hal_i2c_v150_master_write_restore, /* I2C_CTRL_WRITE_RESTORE */
193 hal_i2c_v150_master_read_prepeare, /* I2C_CTRL_READ_PREPARE */
194 hal_i2c_v150_master_read_restore, /* I2C_CTRL_READ_RESTORE */
195 hal_i2c_v150_get_write_num, /* I2C_CTRL_GET_WRITE_NUM */
196 hal_i2c_v150_get_read_num, /* I2C_CTRL_GET_READ_NUM */
197 hal_i2c_v150_ctrl_check_default, /* I2C_CTRL_CHECK_TX_AVAILABLE */
198 hal_i2c_v150_ctrl_check_default, /* I2C_CTRL_CHECK_RX_AVAILABLE */
199 hal_i2c_v150_ctrl_proc_default, /* I2C_CTRL_FLUSH_RX_FIFO */
200 hal_i2c_v150_ctrl_check_default, /* I2C_CTRL_CHECK_TX_PROCESS_DONE */
201 hal_i2c_v150_ctrl_check_default, /* I2C_CTRL_CHECK_RX_PROCESS_DONE */
202 hal_i2c_v150_ctrl_check_default, /* I2C_CTRL_CHECK_RESTART_READY */
203 hal_i2c_v150_ctrl_check_default_false, /* I2C_CTRL_CHECK_TRANSMIT_ABRT */
204 hal_i2c_v150_ctrl_check_default_false, /* I2C_CTRL_GET_DMA_DATA_ADDR */
205 hal_i2c_v150_ctrl_proc_default, /* I2C_CTRL_CHECK_TX_FIFO_EMPTY */
206 };
207
208 #pragma weak hal_i2c_master_init = hal_i2c_v150_master_init
hal_i2c_v150_master_init(i2c_bus_t bus,uint32_t baudrate,uint8_t hscode,hal_i2c_callback_t callback)209 errcode_t hal_i2c_v150_master_init(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode, hal_i2c_callback_t callback)
210 {
211 unused(hscode);
212
213 hal_i2c_speed_mode_t speed_mode = hal_i2c_v150_get_speed_mode(baudrate);
214 if (speed_mode == I2C_SPEED_MODE_HS) {
215 return ERRCODE_I2C_RATE_INVALID;
216 }
217
218 hal_i2c_ctrl_info_t *hal_i2c_ctrl_info = hal_i2c_v150_get_ctrl_info(bus);
219 if (hal_i2c_ctrl_info->init) {
220 // 根据驱动层逻辑, 在已初始化的情况下再次初始化视为设置波特率
221 hal_i2c_v150_cfg_clk(bus, baudrate, hal_i2c_ctrl_info->cfg_scl_h, hal_i2c_ctrl_info->cfg_scl_l);
222 return ERRCODE_SUCC;
223 }
224
225 hal_i2c_v150_regs_init(bus);
226 hal_i2c_v150_reset_all_regs(bus);
227 hal_i2c_v150_cfg_clk(bus, baudrate, hal_i2c_ctrl_info->cfg_scl_h, hal_i2c_ctrl_info->cfg_scl_l);
228 hal_i2c_v150_set_ftrper(bus, I2C_FTRPER_STANDARD_VAL);
229 hal_i2c_v150_unmask_all_int(bus);
230 hal_i2c_v150_unmask_main_int(bus);
231 hal_i2c_v150_load_ctrl_func(bus, g_hal_i2c_master_ctrl_func_array);
232 hal_i2c_v150_register_callback(callback);
233 hal_i2c_v150_set_i2c_enable(bus);
234
235 hal_i2c_ctrl_info->baudrate = baudrate;
236 hal_i2c_ctrl_info->init = I2C_TRUE;
237
238 return ERRCODE_SUCC;
239 }
240
241 #pragma weak hal_i2c_slave_init = hal_i2c_v150_slave_init
hal_i2c_v150_slave_init(i2c_bus_t bus,uint32_t baudrate,uint16_t addr,hal_i2c_callback_t callback)242 errcode_t hal_i2c_v150_slave_init(i2c_bus_t bus, uint32_t baudrate, uint16_t addr, hal_i2c_callback_t callback)
243 {
244 unused(bus);
245 unused(baudrate);
246 unused(addr);
247 unused(callback);
248 return ERRCODE_NOT_SUPPORT;
249 }