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