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 "uart_hw.h"
19 #include "hal_port.h"
20 #include <driver/hal/hal_uart_types.h>
21 #include <driver/hal/hal_gpio_types.h>
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 #define UART_LL_REG_BASE(_uart_unit_id) (uart_ll_reg_base_select(_uart_unit_id))
28 #define CASE_PARITY(parity) case UART_PARITY_##parity: return UART_V_PARITY_##parity
29 #define CASE_D() default: return 0
30
31 #define UART1_FLOW_CTRL_CNT 0xCC
32
33 #define UART1_LL_TX_PIN GPIO_11
34 #define UART1_LL_RX_PIN GPIO_10
35 #define UART1_LL_CTS_PIN GPIO_12
36 #define UART1_LL_RTS_PIN GPIO_13
37
38
39 #define UART2_LL_TX_PIN GPIO_0
40 #define UART2_LL_RX_PIN GPIO_1
41
uart_ll_init(uart_hw_t * hw)42 static inline void uart_ll_init(uart_hw_t *hw)
43 {
44
45 }
46
uart_ll_get_tx_pin(uart_id_t id)47 static inline gpio_id_t uart_ll_get_tx_pin(uart_id_t id)
48 {
49 switch (id)
50 {
51 case UART_ID_0:
52 return UART1_LL_TX_PIN;
53 case UART_ID_1:
54 return UART2_LL_TX_PIN;
55 default:
56 return GPIO_NUM;
57 }
58 }
59
uart_ll_get_rx_pin(uart_id_t id)60 static inline gpio_id_t uart_ll_get_rx_pin(uart_id_t id)
61 {
62 switch (id)
63 {
64 case UART_ID_0:
65 return UART1_LL_RX_PIN;
66 case UART_ID_1:
67 return UART2_LL_RX_PIN;
68 default:
69 return GPIO_NUM;
70 }
71 }
72
uart_ll_get_cts_pin(uart_id_t id)73 static inline gpio_id_t uart_ll_get_cts_pin(uart_id_t id)
74 {
75 switch (id)
76 {
77 case UART_ID_0:
78 return UART1_LL_CTS_PIN;
79 default:
80 return GPIO_NUM;
81 }
82 }
83
uart_ll_get_rts_pin(uart_id_t id)84 static inline gpio_id_t uart_ll_get_rts_pin(uart_id_t id)
85 {
86 switch (id)
87 {
88 case UART_ID_0:
89 return UART1_LL_RTS_PIN;
90 default:
91 return GPIO_NUM;
92 }
93 }
94
uart_ll_reg_base_select(uart_id_t id)95 static inline uint32_t uart_ll_reg_base_select(uart_id_t id)
96 {
97 switch (id)
98 {
99 case UART_ID_0:
100 return UART1_R_BASE;
101 case UART_ID_1:
102 return UART2_R_BASE;
103 default:
104 return BK_ERR_UART_BASE;
105 break;
106 }
107 }
108
uart_ll_to_reg_parity(uart_parity_t parity)109 static inline uint32_t uart_ll_to_reg_parity(uart_parity_t parity)
110 {
111 switch (parity)
112 {
113 CASE_PARITY(ODD);
114 CASE_PARITY(EVEN);
115 CASE_D();
116 }
117 }
118
uart_ll_set_tx_enable(uart_hw_t * hw,uart_id_t id,uint32_t value)119 static inline void uart_ll_set_tx_enable(uart_hw_t *hw, uart_id_t id, uint32_t value)
120 {
121 hw->config.tx_enable = value & 0x01;
122 }
123
uart_ll_enable_tx(uart_hw_t * hw,uart_id_t id)124 static inline void uart_ll_enable_tx(uart_hw_t *hw, uart_id_t id)
125 {
126 uart_ll_set_tx_enable(hw, id, 1);
127 }
128
uart_ll_disable_tx(uart_hw_t * hw,uart_id_t id)129 static inline void uart_ll_disable_tx(uart_hw_t *hw, uart_id_t id)
130 {
131 uart_ll_set_tx_enable(hw, id, 0);
132 }
133
uart_ll_set_rx_enable(uart_hw_t * hw,uart_id_t id,uint32_t value)134 static inline void uart_ll_set_rx_enable(uart_hw_t *hw, uart_id_t id, uint32_t value)
135 {
136 hw->config.rx_enable = value & 0x1;
137 }
138
uart_ll_enable_rx(uart_hw_t * hw,uart_id_t id)139 static inline void uart_ll_enable_rx(uart_hw_t *hw, uart_id_t id)
140 {
141 uart_ll_set_rx_enable(hw, id, 1);
142 }
143
uart_ll_set_frame_mode(uart_hw_t * hw,uart_id_t id,uart_frame_mode_t mode)144 static inline void uart_ll_set_frame_mode(uart_hw_t *hw, uart_id_t id, uart_frame_mode_t mode)
145 {
146 hw->config.mode = mode;
147 }
148
uart_ll_set_mode_uart(uart_hw_t * hw,uart_id_t id)149 static inline void uart_ll_set_mode_uart(uart_hw_t *hw, uart_id_t id)
150 {
151 hw->config.mode = UART_V_MODE_UART;
152 }
153
uart_ll_set_mode_irda(uart_hw_t * hw,uart_id_t id)154 static inline void uart_ll_set_mode_irda(uart_hw_t *hw, uart_id_t id)
155 {
156 hw->config.mode = UART_V_MODE_IRDA;
157 }
158
uart_ll_disable_rx(uart_hw_t * hw,uart_id_t id)159 static inline void uart_ll_disable_rx(uart_hw_t *hw, uart_id_t id)
160 {
161 uart_ll_set_rx_enable(hw, id, 0);
162 }
163
uart_ll_set_data_bits(uart_hw_t * hw,uart_id_t id,uart_data_bits_t value)164 static inline void uart_ll_set_data_bits(uart_hw_t *hw, uart_id_t id, uart_data_bits_t value)
165 {
166 hw->config.data_bits = value & 0x3;
167 }
168
uart_ll_enable_parity(uart_hw_t * hw,uart_id_t id)169 static inline void uart_ll_enable_parity(uart_hw_t *hw, uart_id_t id)
170 {
171 hw->config.parity_en = 1;
172 }
173
uart_ll_disable_parity(uart_hw_t * hw,uart_id_t id)174 static inline void uart_ll_disable_parity(uart_hw_t *hw, uart_id_t id)
175 {
176 hw->config.parity_en = 0;
177 }
178
uart_ll_set_parity(uart_hw_t * hw,uart_id_t id,uart_parity_t value)179 static inline void uart_ll_set_parity(uart_hw_t *hw, uart_id_t id, uart_parity_t value)
180 {
181 hw->config.parity = uart_ll_to_reg_parity(value);
182 }
183
uart_ll_set_stop_bits(uart_hw_t * hw,uart_id_t id,uart_stop_bits_t value)184 static inline void uart_ll_set_stop_bits(uart_hw_t *hw, uart_id_t id, uart_stop_bits_t value)
185 {
186 hw->config.stop_bits = value;
187 }
188
uart_ll_set_clk_div(uart_hw_t * hw,uart_id_t id,uint32_t value)189 static inline void uart_ll_set_clk_div(uart_hw_t *hw, uart_id_t id, uint32_t value)
190 {
191 hw->config.clk_div = value & UART_F_CLK_DIV_M;
192 }
193
uart_ll_set_tx_fifo_threshold(uart_hw_t * hw,uart_id_t id,uint32_t value)194 static inline void uart_ll_set_tx_fifo_threshold(uart_hw_t *hw, uart_id_t id, uint32_t value)
195 {
196 hw->fifo_config.tx_fifo_threshold = value & 0xff;
197 }
198
uart_ll_set_rx_fifo_threshold(uart_hw_t * hw,uart_id_t id,uint32_t value)199 static inline void uart_ll_set_rx_fifo_threshold(uart_hw_t *hw, uart_id_t id, uint32_t value)
200 {
201 hw->fifo_config.rx_fifo_threshold = value & 0xff;
202 }
203
uart_ll_set_rx_stop_detect_time(uart_hw_t * hw,uart_id_t id,uint32_t value)204 static inline void uart_ll_set_rx_stop_detect_time(uart_hw_t *hw, uart_id_t id, uint32_t value)
205 {
206 hw->fifo_config.rx_stop_detect_time = value & 0x3;
207 }
208
uart_ll_reset_config_to_default(uart_hw_t * hw,uart_id_t id)209 static inline void uart_ll_reset_config_to_default(uart_hw_t *hw, uart_id_t id)
210 {
211 hw->config.v = 0;
212 hw->fifo_config.v = 0;
213 }
214
uart_ll_get_tx_fifo_cnt(uart_hw_t * hw,uart_id_t id)215 static inline uint32_t uart_ll_get_tx_fifo_cnt(uart_hw_t *hw, uart_id_t id)
216 {
217 return hw->fifo_status.tx_fifo_count;
218 }
219
uart_ll_get_rx_fifo_cnt(uart_hw_t * hw,uart_id_t id)220 static inline uint32_t uart_ll_get_rx_fifo_cnt(uart_hw_t *hw, uart_id_t id)
221 {
222 return hw->fifo_status.rx_fifo_count;
223 }
224
uart_ll_is_tx_fifo_full(uart_hw_t * hw,uart_id_t id)225 static inline bool uart_ll_is_tx_fifo_full(uart_hw_t *hw, uart_id_t id)
226 {
227 return !!(hw->fifo_status.tx_fifo_full);
228 }
229
uart_ll_is_tx_fifo_empty(uart_hw_t * hw,uart_id_t id)230 static inline bool uart_ll_is_tx_fifo_empty(uart_hw_t *hw, uart_id_t id)
231 {
232 return !!(hw->fifo_status.tx_fifo_empty);
233 }
234
uart_ll_is_rx_fifo_full(uart_hw_t * hw,uart_id_t id)235 static inline bool uart_ll_is_rx_fifo_full(uart_hw_t *hw, uart_id_t id)
236 {
237 return !!(hw->fifo_status.rx_fifo_full);
238 }
239
uart_ll_is_rx_fifo_empty(uart_hw_t * hw,uart_id_t id)240 static inline bool uart_ll_is_rx_fifo_empty(uart_hw_t *hw, uart_id_t id)
241 {
242 return !!(hw->fifo_status.rx_fifo_empty);
243 }
244
uart_ll_is_fifo_write_ready(uart_hw_t * hw,uart_id_t id)245 static inline bool uart_ll_is_fifo_write_ready(uart_hw_t *hw, uart_id_t id)
246 {
247 return !!(hw->fifo_status.fifo_wr_ready);
248 }
249
uart_ll_is_fifo_read_ready(uart_hw_t * hw,uart_id_t id)250 static inline bool uart_ll_is_fifo_read_ready(uart_hw_t *hw, uart_id_t id)
251 {
252 return !!(hw->fifo_status.fifo_rd_ready);
253 }
254
uart_ll_reset_fifo_port_to_default(uart_hw_t * hw,uart_id_t id)255 static inline void uart_ll_reset_fifo_port_to_default(uart_hw_t *hw, uart_id_t id)
256 {
257 hw->fifo_port.v = 0xffff;
258 }
259
uart_ll_write_byte(uart_hw_t * hw,uart_id_t id,uint8_t data)260 static inline void uart_ll_write_byte(uart_hw_t *hw, uart_id_t id, uint8_t data)
261 {
262 /* note: hw->fifo_port.tx_fifo_data_in = data; is incorrect */
263 hw->fifo_port.v = data & 0xff;
264 }
265
uart_ll_read_byte(uart_hw_t * hw,uart_id_t id)266 static inline uint8_t uart_ll_read_byte(uart_hw_t *hw, uart_id_t id)
267 {
268 return hw->fifo_port.rx_fifo_data_out;
269 }
270
uart_ll_reset_int_en_to_default(uart_hw_t * hw,uart_id_t id)271 static inline void uart_ll_reset_int_en_to_default(uart_hw_t *hw, uart_id_t id)
272 {
273 hw->int_enable.v = 0;
274 }
275
uart_ll_enable_rx_interrupt(uart_hw_t * hw,uart_id_t id)276 static inline void uart_ll_enable_rx_interrupt(uart_hw_t *hw, uart_id_t id)
277 {
278 hw->int_enable.rx_fifo_need_read = 1;
279 hw->int_enable.rx_finish = 1;
280 }
281
uart_ll_disable_rx_interrupt(uart_hw_t * hw,uart_id_t id)282 static inline void uart_ll_disable_rx_interrupt(uart_hw_t *hw, uart_id_t id)
283 {
284 hw->int_enable.rx_fifo_need_read = 0;
285 hw->int_enable.rx_finish = 0;
286 }
287
uart_ll_enable_tx_interrupt(uart_hw_t * hw,uart_id_t id)288 static inline void uart_ll_enable_tx_interrupt(uart_hw_t *hw, uart_id_t id)
289 {
290 hw->int_enable.tx_fifo_need_write = 1;
291 }
292
uart_ll_disable_tx_interrupt(uart_hw_t * hw,uart_id_t id)293 static inline void uart_ll_disable_tx_interrupt(uart_hw_t *hw, uart_id_t id)
294 {
295 hw->int_enable.tx_fifo_need_write = 0;
296 }
297
uart_ll_get_int_enable_status(uart_hw_t * hw,uart_id_t id)298 static inline uint32_t uart_ll_get_int_enable_status(uart_hw_t *hw, uart_id_t id)
299 {
300 return hw->int_enable.v & 0xff;
301 }
302
uart_ll_get_interrupt_status(uart_hw_t * hw,uart_id_t id)303 static inline uint32_t uart_ll_get_interrupt_status(uart_hw_t *hw, uart_id_t id)
304 {
305 return hw->int_status.v & 0xff;
306 }
307
uart_ll_clear_interrupt_status(uart_hw_t * hw,uart_id_t id,uint32_t status)308 static inline void uart_ll_clear_interrupt_status(uart_hw_t *hw, uart_id_t id, uint32_t status)
309 {
310 hw->int_status.v = status & 0xff;
311 }
312
uart_ll_clear_id_interrupt_status(uart_hw_t * hw,uart_id_t id)313 static inline void uart_ll_clear_id_interrupt_status(uart_hw_t *hw, uart_id_t id)
314 {
315 hw->int_status.v = 0xff;
316 }
317
uart_ll_clear_id_tx_interrupt_status(uart_hw_t * hw,uart_id_t id)318 static inline void uart_ll_clear_id_tx_interrupt_status(uart_hw_t *hw, uart_id_t id)
319 {
320 hw->int_status.tx_fifo_need_write = 1;
321 hw->int_status.tx_finish = 1;
322 }
323
uart_ll_clear_id_rx_interrupt_status(uart_hw_t * hw,uart_id_t id)324 static inline void uart_ll_clear_id_rx_interrupt_status(uart_hw_t *hw, uart_id_t id)
325 {
326 hw->int_status.rx_fifo_need_read = 1;
327 hw->int_status.rx_finish = 1;
328 }
329
uart_ll_is_rx_interrupt_triggered(uart_hw_t * hw,uart_id_t id,uint32_t status)330 static inline bool uart_ll_is_rx_interrupt_triggered(uart_hw_t *hw, uart_id_t id, uint32_t status)
331 {
332 return !!(status & (BIT(1) | BIT(6)));
333 }
334
uart_ll_is_rx_recv_fini_int_triggered(uart_hw_t * hw,uart_id_t id,uint32_t status)335 static inline bool uart_ll_is_rx_recv_fini_int_triggered(uart_hw_t *hw, uart_id_t id, uint32_t status)
336 {
337 return !!(status & BIT(6));
338 }
339
uart_ll_is_tx_interrupt_triggered(uart_hw_t * hw,uart_id_t id,uint32_t status)340 static inline bool uart_ll_is_tx_interrupt_triggered(uart_hw_t *hw, uart_id_t id, uint32_t status)
341 {
342 return !!(status & BIT(0));
343 }
344
uart_ll_is_rx_parity_err_int_triggered(uart_hw_t * hw,uart_id_t id,uint32_t status)345 static inline bool uart_ll_is_rx_parity_err_int_triggered(uart_hw_t *hw, uart_id_t id, uint32_t status)
346 {
347 return !!(status & BIT(3));
348 }
349
uart_ll_reset_flow_control_to_default(uart_hw_t * hw,uart_id_t id)350 static inline void uart_ll_reset_flow_control_to_default(uart_hw_t *hw, uart_id_t id)
351 {
352 hw->flow_ctrl_config.v = 0;
353 }
354
uart_ll_enable_flow_control(uart_hw_t * hw,uart_id_t id)355 static inline void uart_ll_enable_flow_control(uart_hw_t *hw, uart_id_t id)
356 {
357 hw->flow_ctrl_config.flow_ctrl_en = 1;
358 }
359
uart_ll_disable_flow_control(uart_hw_t * hw,uart_id_t id)360 static inline void uart_ll_disable_flow_control(uart_hw_t *hw, uart_id_t id)
361 {
362 hw->flow_ctrl_config.flow_ctrl_en = 0;
363 }
364
uart_ll_is_flow_control_enabled(uart_hw_t * hw,uart_id_t id)365 static inline bool uart_ll_is_flow_control_enabled(uart_hw_t *hw, uart_id_t id)
366 {
367 return !!(hw->flow_ctrl_config.flow_ctrl_en);
368 }
369
uart_ll_set_flow_control_low_cnt(uart_hw_t * hw,uart_id_t id,uint32_t cnt)370 static inline void uart_ll_set_flow_control_low_cnt(uart_hw_t *hw, uart_id_t id, uint32_t cnt)
371 {
372 hw->flow_ctrl_config.flow_ctrl_low_cnt = cnt & 0xff;
373 }
374
uart_ll_set_flow_control_high_cnt(uart_hw_t * hw,uart_id_t id,uint32_t cnt)375 static inline void uart_ll_set_flow_control_high_cnt(uart_hw_t *hw, uart_id_t id, uint32_t cnt)
376 {
377 hw->flow_ctrl_config.flow_ctrl_high_cnt = cnt & 0xff;
378 }
379
uart_ll_set_rts_polarity(uart_hw_t * hw,uart_id_t id,uint32_t value)380 static inline void uart_ll_set_rts_polarity(uart_hw_t *hw, uart_id_t id, uint32_t value)
381 {
382 hw->flow_ctrl_config.rts_polarity_sel = value & 0x1;
383 }
384
uart_ll_set_cts_polarity(uart_hw_t * hw,uart_id_t id,uint32_t value)385 static inline void uart_ll_set_cts_polarity(uart_hw_t *hw, uart_id_t id, uint32_t value)
386 {
387 hw->flow_ctrl_config.cts_polarity_sel = value & 0x1;
388 }
389
uart_ll_reset_wake_config_to_default(uart_hw_t * hw,uart_id_t id)390 static inline void uart_ll_reset_wake_config_to_default(uart_hw_t *hw, uart_id_t id)
391 {
392 hw->wake_config.v = 0;
393 }
394
uart_ll_wait_tx_over(void)395 static inline uint32_t uart_ll_wait_tx_over(void)
396 {
397 uint32_t uart_wait_us;
398 uint32_t baudrate1;
399 uint32_t baudrate2;
400 uart_hw_t *hw1 = (uart_hw_t *)UART_LL_REG_BASE(0);
401 uart_hw_t *hw2 = (uart_hw_t *)UART_LL_REG_BASE(1);
402
403 baudrate1 = UART_CLOCK / (hw1->config.clk_div + 1);
404 baudrate2 = UART_CLOCK / (hw2->config.clk_div + 1);
405
406 uart_wait_us = 1000000 * hw2->fifo_status.tx_fifo_count * 10 / baudrate2
407 + 1000000 * hw1->fifo_status.tx_fifo_count * 10 / baudrate1;
408
409 while (!hw2->fifo_status.tx_fifo_empty);
410 while (!hw1->fifo_status.tx_fifo_empty);
411
412 return uart_wait_us;
413 }
414
415 #ifdef __cplusplus
416 }
417 #endif
418
419