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