• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
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 #pragma once
16 
17 #include <soc/soc.h>
18 #include "hal_port.h"
19 #include <driver/hal/hal_gpio_types.h>
20 #include "i2c_hw.h"
21 #include <driver/hal/hal_i2c_types.h>
22 #include "icu_hw.h"
23 #include "icu_ll.h"
24 #include "power_ll.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #define I2C_LL_REG_BASE(_i2c_unit_id)    (SOC_I2C1_REG_BASE)
31 
32 #define I2C0_LL_SCL_PIN    GPIO_0
33 #define I2C0_LL_SDA_PIN    GPIO_1
34 
i2c_ll_init(i2c_hw_t * hw)35 static inline void i2c_ll_init(i2c_hw_t *hw)
36 {
37 	hw->i2c0_hw = (i2c0_hw_t *)I2C_LL_REG_BASE(0);
38 	hw->i2c0_hw->sm_bus_cfg.v = 0;
39 	hw->i2c0_hw->sm_bus_status.v = 0;
40 }
41 
i2c_ll_enable(i2c_hw_t * hw,i2c_id_t id)42 static inline void i2c_ll_enable(i2c_hw_t *hw, i2c_id_t id)
43 {
44 		hw->i2c0_hw->sm_bus_cfg.en = 1;
45 }
46 
i2c_ll_disable(i2c_hw_t * hw,i2c_id_t id)47 static inline void i2c_ll_disable(i2c_hw_t *hw, i2c_id_t id)
48 {
49 		hw->i2c0_hw->sm_bus_cfg.en = 0;
50 }
51 
i2c_ll_set_pin(i2c_hw_t * hw,i2c_id_t id)52 static inline void i2c_ll_set_pin(i2c_hw_t *hw, i2c_id_t id)
53 {
54 }
55 
i2c_ll_set_idle_detect_threshold(i2c_hw_t * hw,i2c_id_t id,uint32_t threshold)56 static inline void i2c_ll_set_idle_detect_threshold(i2c_hw_t *hw, i2c_id_t id, uint32_t threshold)
57 {
58 		hw->i2c0_hw->sm_bus_cfg.idle_cr = threshold;
59 }
60 
i2c_ll_set_scl_timeout_threshold(i2c_hw_t * hw,i2c_id_t id,uint32_t threshold)61 static inline void i2c_ll_set_scl_timeout_threshold(i2c_hw_t *hw, i2c_id_t id, uint32_t threshold)
62 {
63 		hw->i2c0_hw->sm_bus_cfg.scl_cr = threshold;
64 }
65 
i2c_ll_set_clk_src(i2c_hw_t * hw,i2c_id_t id,uint32_t clk_src)66 static inline void i2c_ll_set_clk_src(i2c_hw_t *hw, i2c_id_t id, uint32_t clk_src)
67 {
68 		hw->i2c0_hw->sm_bus_cfg.clk_src = clk_src;
69 }
70 
i2c_ll_enable_scl_timeout(i2c_hw_t * hw,i2c_id_t id)71 static inline void i2c_ll_enable_scl_timeout(i2c_hw_t *hw, i2c_id_t id)
72 {
73 		hw->i2c0_hw->sm_bus_cfg.timeout_en = 1;
74 }
75 
i2c_ll_disable_scl_timeout(i2c_hw_t * hw,i2c_id_t id)76 static inline void i2c_ll_disable_scl_timeout(i2c_hw_t *hw, i2c_id_t id)
77 {
78 		hw->i2c0_hw->sm_bus_cfg.timeout_en = 0;
79 }
80 
i2c_ll_enable_idle_det(i2c_hw_t * hw,i2c_id_t id)81 static inline void i2c_ll_enable_idle_det(i2c_hw_t *hw, i2c_id_t id)
82 {
83 		hw->i2c0_hw->sm_bus_cfg.idle_det_en = 1;
84 }
85 
i2c_ll_disable_idle_det(i2c_hw_t * hw,i2c_id_t id)86 static inline void i2c_ll_disable_idle_det(i2c_hw_t *hw, i2c_id_t id)
87 {
88 		hw->i2c0_hw->sm_bus_cfg.idle_det_en = 0;
89 }
90 
i2c_ll_enable_slave(i2c_hw_t * hw,i2c_id_t id)91 static inline void i2c_ll_enable_slave(i2c_hw_t *hw, i2c_id_t id)
92 {
93 		hw->i2c0_hw->sm_bus_cfg.inh = 0;
94 }
95 
i2c_ll_disable_slave(i2c_hw_t * hw,i2c_id_t id)96 static inline void i2c_ll_disable_slave(i2c_hw_t *hw, i2c_id_t id)
97 {
98 		hw->i2c0_hw->sm_bus_cfg.inh = 1;
99 }
100 
i2c_ll_set_freq_div(i2c_hw_t * hw,i2c_id_t id,uint32_t freq_div)101 static inline void i2c_ll_set_freq_div(i2c_hw_t *hw, i2c_id_t id, uint32_t freq_div)
102 {
103 		hw->i2c0_hw->sm_bus_cfg.freq_div = freq_div & I2C_F_FREQ_DIV_M;
104 }
105 
i2c_ll_set_slave_addr(i2c_hw_t * hw,i2c_id_t id,uint32_t slave_addr)106 static inline void i2c_ll_set_slave_addr(i2c_hw_t *hw, i2c_id_t id, uint32_t slave_addr)
107 {
108 		hw->i2c0_hw->sm_bus_cfg.slave_addr = slave_addr & I2C_F_SLAVE_ADDR_M;
109 }
110 
i2c_ll_reset_config_to_default(i2c_hw_t * hw,i2c_id_t id)111 static inline void i2c_ll_reset_config_to_default(i2c_hw_t *hw, i2c_id_t id)
112 {
113 		hw->i2c0_hw->sm_bus_cfg.v = 0;
114 }
115 
i2c_ll_enable_start(i2c_hw_t * hw,i2c_id_t id)116 static inline void i2c_ll_enable_start(i2c_hw_t *hw, i2c_id_t id)
117 {
118 		hw->i2c0_hw->sm_bus_status.start = 1;
119 }
120 
i2c_ll_disable_start(i2c_hw_t * hw,i2c_id_t id)121 static inline void i2c_ll_disable_start(i2c_hw_t *hw, i2c_id_t id)
122 {
123 		hw->i2c0_hw->sm_bus_status.start = 0;
124 }
125 
i2c_ll_is_start(i2c_hw_t * hw,i2c_id_t id)126 static inline bool i2c_ll_is_start(i2c_hw_t *hw, i2c_id_t id)
127 {
128 		return !!(hw->i2c0_hw->sm_bus_status.start);
129 }
130 
i2c_ll_is_start_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)131 static inline bool i2c_ll_is_start_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
132 {
133 	return int_status & BIT(10);
134 }
135 
i2c_ll_enable_stop(i2c_hw_t * hw,i2c_id_t id)136 static inline void i2c_ll_enable_stop(i2c_hw_t *hw, i2c_id_t id)
137 {
138 		/* sm_int and stop (bit[0] and bit[9]) must set together,
139 		 * otherwize i2c stop will not work.
140 		 * e.g.
141 		 * case 1: i2c stop not work
142 		 * hw->i2c1_hw->int_status.stop = 1;
143 		 * or REG_SET_BIT(I2C1_R_INT_STAUS, BIT(9));
144 		 *
145 		 * case 2: i2c stop not work
146 		 * hw->i2c1_hw->int_status.stop = 1;
147 		 * hw->i2c1_hw->int_status.sm_int = 0;
148 		 *
149 		 * case 3: i2c stop not work
150 		 * hw->i2c1_hw->int_status.sm_int = 0;
151 		 * hw->i2c1_hw->int_status.stop = 1;
152  		 */
153 }
154 
i2c_ll_disable_stop(i2c_hw_t * hw,i2c_id_t id)155 static inline void i2c_ll_disable_stop(i2c_hw_t *hw, i2c_id_t id)
156 {
157 		hw->i2c0_hw->sm_bus_status.stop = 0;
158 }
159 
i2c_ll_is_stop_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)160 static inline bool i2c_ll_is_stop_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
161 {
162 	return int_status & BIT(9);
163 }
164 
i2c_ll_set_write_int_mode(i2c_hw_t * hw,i2c_id_t id,i2c_fifo_int_level_t int_mode)165 static inline void i2c_ll_set_write_int_mode(i2c_hw_t *hw, i2c_id_t id, i2c_fifo_int_level_t int_mode)
166 {
167 		switch (int_mode) {
168 		case I2C_FIFO_INT_LEVEL_1:
169 			hw->i2c0_hw->sm_bus_status.int_mode = 0;
170 			break;
171 		case I2C_FIFO_INT_LEVEL_4:
172 			hw->i2c0_hw->sm_bus_status.int_mode = 1;
173 			break;
174 		case I2C_FIFO_INT_LEVEL_8:
175 			hw->i2c0_hw->sm_bus_status.int_mode = 2;
176 			break;
177 		case I2C_FIFO_INT_LEVEL_12:
178 			hw->i2c0_hw->sm_bus_status.int_mode = 3;
179 			break;
180 		default:
181 			break;
182 		}
183 }
184 
i2c_ll_set_read_int_mode(i2c_hw_t * hw,i2c_id_t id,i2c_fifo_int_level_t int_mode)185 static inline void i2c_ll_set_read_int_mode(i2c_hw_t *hw, i2c_id_t id, i2c_fifo_int_level_t int_mode)
186 {
187 		switch (int_mode) {
188 		case I2C_FIFO_INT_LEVEL_1:
189 			hw->i2c0_hw->sm_bus_status.int_mode = 3;
190 			break;
191 		case I2C_FIFO_INT_LEVEL_4:
192 			hw->i2c0_hw->sm_bus_status.int_mode = 2;
193 			break;
194 		case I2C_FIFO_INT_LEVEL_8:
195 			hw->i2c0_hw->sm_bus_status.int_mode = 1;
196 			break;
197 		case I2C_FIFO_INT_LEVEL_12:
198 			hw->i2c0_hw->sm_bus_status.int_mode = 0;
199 			break;
200 		default:
201 			break;
202 		}
203 }
204 
i2c_ll_get_write_empty_fifo_num(i2c_hw_t * hw,i2c_id_t id)205 static inline uint32_t i2c_ll_get_write_empty_fifo_num(i2c_hw_t *hw, i2c_id_t id)
206 {
207 		switch (hw->i2c0_hw->sm_bus_status.int_mode) {
208 		case 0x00:
209 			return 16;
210 		case 0x01:
211 			return 12;
212 		case 0x02:
213 			return 8;
214 		case 0x03:
215 			return 4;
216 		default:
217 			return 0;
218 		}
219 }
220 
i2c_ll_get_read_fifo_num(i2c_hw_t * hw,i2c_id_t id)221 static inline uint32_t i2c_ll_get_read_fifo_num(i2c_hw_t *hw, i2c_id_t id)
222 {
223 		switch (hw->i2c0_hw->sm_bus_status.int_mode)
224 		{
225 		case 0x00:
226 			return 12;
227 		case 0x01:
228 			return 8;
229 		case 0x02:
230 			return 4;
231 		case 0x03:
232 			return 1;
233 		default:
234 			return 0;
235 		}
236 }
237 
i2c_ll_is_busy(i2c_hw_t * hw,i2c_id_t id)238 static inline bool i2c_ll_is_busy(i2c_hw_t *hw, i2c_id_t id)
239 {
240 		return !!(hw->i2c0_hw->sm_bus_status.busy);
241 }
242 
i2c_ll_is_addr_matched(i2c_hw_t * hw,i2c_id_t id)243 static inline bool i2c_ll_is_addr_matched(i2c_hw_t *hw, i2c_id_t id)
244 {
245 		return !!(hw->i2c0_hw->sm_bus_status.addr_match);
246 }
247 
i2c_ll_is_tx_mode(i2c_hw_t * hw,i2c_id_t id)248 static inline bool i2c_ll_is_tx_mode(i2c_hw_t *hw, i2c_id_t id)
249 {
250 		return !!(hw->i2c0_hw->sm_bus_status.tx_mode);
251 }
252 
i2c_ll_is_rx_mode(i2c_hw_t * hw,i2c_id_t id)253 static inline bool i2c_ll_is_rx_mode(i2c_hw_t *hw, i2c_id_t id)
254 {
255 		return !(hw->i2c0_hw->sm_bus_status.tx_mode);
256 }
257 
i2c_ll_get_interrupt_status(i2c_hw_t * hw,i2c_id_t id)258 static inline uint32_t i2c_ll_get_interrupt_status(i2c_hw_t *hw, i2c_id_t id)
259 {
260 		return hw->i2c0_hw->sm_bus_status.v;
261 }
262 
i2c_ll_clear_interrupt_status(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)263 static inline void i2c_ll_clear_interrupt_status(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
264 {
265 		if (int_status & I2C0_F_SM_INT) {
266 			int_status &= ~I2C0_F_SM_INT; /* clear sm_bus_int */
267 		}
268 		REG_WRITE(I2C0_R_INT_STAUS, int_status);
269 }
270 
i2c_ll_is_sm_int_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)271 static inline bool i2c_ll_is_sm_int_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
272 {
273 	return !!(int_status & BIT(0));
274 }
275 
i2c_ll_is_scl_timeout_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)276 static inline bool i2c_ll_is_scl_timeout_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
277 {
278 	return !!(int_status & BIT(1));
279 }
280 
i2c_ll_is_arb_lost_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)281 static inline bool i2c_ll_is_arb_lost_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
282 {
283 	return !!(int_status & BIT(3));
284 }
285 
i2c_ll_is_rx_ack_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)286 static inline bool i2c_ll_is_rx_ack_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
287 {
288 	return !!(int_status & BIT(8));
289 }
290 
i2c_ll_is_tx_ack_triggered(i2c_hw_t * hw,i2c_id_t id,uint32_t int_status)291 static inline bool i2c_ll_is_tx_ack_triggered(i2c_hw_t *hw, i2c_id_t id, uint32_t int_status)
292 {
293 	return !!(int_status & BIT(8));
294 }
295 
i2c_ll_tx_ack(i2c_hw_t * hw,i2c_id_t id)296 static inline void i2c_ll_tx_ack(i2c_hw_t *hw, i2c_id_t id)
297 {
298 }
299 
i2c_ll_tx_non_ack(i2c_hw_t * hw,i2c_id_t id)300 static inline void i2c_ll_tx_non_ack(i2c_hw_t *hw, i2c_id_t id)
301 {
302 		hw->i2c0_hw->sm_bus_status.ack = 0;
303 }
304 
i2c_ll_set_tx_mode(i2c_hw_t * hw,i2c_id_t id)305 static inline void i2c_ll_set_tx_mode(i2c_hw_t *hw, i2c_id_t id)
306 {
307 }
308 
i2c_ll_set_rx_mode(i2c_hw_t * hw,i2c_id_t id)309 static inline void i2c_ll_set_rx_mode(i2c_hw_t *hw, i2c_id_t id)
310 {
311 }
312 
i2c_ll_write_byte(i2c_hw_t * hw,i2c_id_t id,uint32_t data)313 static inline void i2c_ll_write_byte(i2c_hw_t *hw, i2c_id_t id, uint32_t data)
314 {
315 		hw->i2c0_hw->sm_bus_data.data = data & I2C_F_DATA_M;
316 }
317 
i2c_ll_read_byte(i2c_hw_t * hw,i2c_id_t id)318 static inline uint8_t i2c_ll_read_byte(i2c_hw_t *hw, i2c_id_t id)
319 {
320 		return hw->i2c0_hw->sm_bus_data.data;
321 }
322 
323 #ifdef __cplusplus
324 }
325 #endif
326 
327