• 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 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 }