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 * Description: UART HAL Driver.
15 *
16 * Create: 2023-2-17
17 */
18
19 #include "chip_io.h"
20 #include "soc_osal.h"
21 #include "platform_types.h"
22 #include "hal_uart.h"
23 #include "hal_uart_v151_regs_def.h"
24 #include "hal_uart_v151_regs_op.h"
25 #include "tcxo.h"
26
27 #define hal_uart_get_high_8bit(val) ((val) >> 8)
28 #define hal_uart_get_low_8bit(val) ((val) & 0xff)
29 #define round_off(val) ((uint32_t)((val) + 1 / 2))
30
31 #define HAL_UART_FIFO_DEPTH_SHIFT_2 2
32 #define HAL_UART_FIFO_DEPTH_MINUS_2 2
33 #define HAL_UART_FIFO_DEPTH_MULTIPLE 16
34
35 #define HAL_UART_BARD_LEFT_SHIFT_2 2
36 #define HAL_UART_BARD_LEFT_SHIFT_6 6
37 #define HAL_UART_INIT_DELAY_10US 10
38
39 #define IBRD_NEED_BAUD_OFFSET_NUM 4
40 #define REMAINDER_NEED_BAUD_OFFSET_NUM 4
41 #define HAL_UART_GET_BAUD_RATE_SHIFT 8
42
43 /** Uart FIFO Level */
44 typedef enum {
45 HAL_UART_RX_FIFO_AVAILABLE_LEVEL_EQ_1 = 0, // 1 character in FIFO
46 HAL_UART_TX_FIFO_EMPTY_LEVEL_EQ_0 = 0, // FIFO Empty
47 HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4 = 1, // FIFO 1/4 full
48 HAL_UART_TX_FIFO_EMPTY_LEVEL_EQ_2 = 1, // 2 characters in FIFO
49 HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_2 = 2, // FIFO 1/2 full
50 HAL_UART_TX_FIFO_EMPTY_LEVEL_1_4 = 2, // FIFO 1/4 full
51 HAL_UART_RX_FIFO_AVAILABLE_LEVEL_LESS_2 = 3, // FIFO 2 less than full
52 HAL_UART_TX_FIFO_EMPTY_LEVEL_1_2 = 3, // FIFO 1/2 full
53 } hal_uart_fifo_int_lvl_t;
54
55 /**
56 * @brief Sets the FIFO interrupt leves for receiving and transmitting.
57 * @param uart Uart bus.
58 * @param rx_level Level at which the receive interrupt interrupt will be triggered.
59 * @param tx_level Level at which the transmit interrupt interrupt will be triggered.
60 */
61 void hal_uart_init_fifo(uart_bus_t uart, hal_uart_fifo_int_lvl_t rx_level, hal_uart_fifo_int_lvl_t tx_level);
62
63 void hal_uart_set_data_bits(uart_bus_t uart, hal_uart_data_bit_t bits);
64
65 /**
66 * @brief UART TX interrupt and DMA request signal trigger by TX fifo level.
67 * @param uart Uart bus.
68 * @param value Programmable the interrupt mode enable or disable
69 */
70 void hal_uart_set_ptim_en(uart_bus_t uart, bool value);
71
72 void hal_uart_auto_flow_ctl_en(uart_bus_t bus, hal_uart_auto_flow_ctl_t auto_flow);
73
74 /**
75 * Base addresses of all UARTS supported by the core
76 */
77 uart_reg_t *g_hal_uart_reg[UART_BUS_MAX_NUMBER];
78
79 /* flag to force the execution of the tx interrupt even if the tx condition is not triggered */
80 #define HAL_UART_FORCE_TX_ISR_FLAG 0x01
81 #define HAL_UART_FORCE_IDLE_ISR_FLAG 0x02
82 static uint8_t g_hal_uart_force_isr_flags[UART_BUS_MAX_NUMBER];
83 static hal_uart_callback_t g_hal_uart_callback[UART_BUS_MAX_NUMBER] = { 0 };
84
85 hal_uart_fifo_int_lvl_t g_hal_uart_rx_fifo_level[UART_BUS_MAX_NUMBER];
86 hal_uart_fifo_int_lvl_t g_hal_uart_tx_fifo_level[UART_BUS_MAX_NUMBER];
87
88 #ifdef BUILD_APPLICATION_STANDARD
89 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
90 #include "log_printf.h"
91 #define hal_uart_print_err(log_id, fmt, count, args...) \
92 BASE_PRINT_ERR(CONNECT(LOG_BCORE_PLT_DRIVER_UART, log_id), fmt, count, ##args)
93 #define hal_uart_print_info(log_id, fmt, count, args...) \
94 BASE_PRINT_INFO(CONNECT(LOG_BCORE_PLT_DRIVER_UART, log_id), fmt, count, ##args)
95 #endif
96 #endif
97 static errcode_t hal_uart_is_tx_fifo_full(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param);
98 static errcode_t hal_uart_is_tx_fifo_empty(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param);
99 static errcode_t hal_uart_is_rx_fifo_empty(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param);
100 static errcode_t hal_uart_is_busy(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param);
101 #if defined(CONFIG_UART_SUPPORT_DMA)
102 static errcode_t hal_uart_v151_get_dma_data_addr(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param);
103 #endif
104
hal_uart_init_reg_base(uart_bus_t uart)105 static void hal_uart_init_reg_base(uart_bus_t uart)
106 {
107 g_hal_uart_reg[uart] = (uart_reg_t *)g_uart_base_addrs[uart];
108 g_hal_uart_reg[0] = (uart_reg_t *)g_uart_base_addrs[0];
109 }
110
hal_uart_v151_init(uart_bus_t uart,hal_uart_callback_t callback,const hal_uart_pin_config_t * pins,const hal_uart_attr_t * attr,hal_uart_flow_ctrl_t flow_ctrl)111 static errcode_t hal_uart_v151_init(uart_bus_t uart, hal_uart_callback_t callback, const hal_uart_pin_config_t *pins,
112 const hal_uart_attr_t *attr, hal_uart_flow_ctrl_t flow_ctrl)
113 {
114 unused(pins);
115
116 hal_uart_init_reg_base(uart);
117 g_hal_uart_force_isr_flags[uart] = 0;
118
119 hal_uart_set_data_bits(uart, attr->data_bits);
120 hal_uart_set_stop_bits(uart, attr->stop_bits);
121 hal_uart_set_parity(uart, attr->parity);
122
123 // specific priority of irq associated with uart
124
125 hal_uart_sir_mode_en(uart, false);
126 hal_uart_tx_pause_en(uart, false);
127
128 hal_uart_set_baud_rate(uart, attr->baud_rate, uart_port_get_clock_value(uart));
129 uapi_tcxo_delay_us(HAL_UART_INIT_DELAY_10US);
130 #ifdef HSO_SUPPORT
131 hal_uart_init_fifo(uart, HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4, HAL_UART_TX_FIFO_EMPTY_LEVEL_EQ_2);
132 #else
133 hal_uart_init_fifo(uart, HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4, HAL_UART_TX_FIFO_EMPTY_LEVEL_EQ_2);
134 #endif
135 g_hal_uart_callback[uart] = callback;
136 if (flow_ctrl == UART_FLOW_CTRL_RTS_CTS) {
137 hal_uart_auto_flow_ctl_en(uart, HAL_UART_AUTO_FLOW_CTL_ENABLED);
138 } else {
139 hal_uart_auto_flow_ctl_en(uart, HAL_UART_AUTO_FLOW_CTL_DISABLED);
140 }
141
142 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
143 hal_uart_set_ptim_en(uart, true);
144 hal_uart_rx_en(uart, true);
145 #endif
146 return ERRCODE_SUCC;
147 }
148
149 #if defined(CONFIG_UART_SUPPORT_TX_INT)
hal_uart_en_tx_int(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)150 static errcode_t hal_uart_en_tx_int(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
151 {
152 unused(id);
153 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_TX, param);
154 return ERRCODE_SUCC;
155 }
156 #endif
157
hal_uart_en_rx_int(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)158 static errcode_t hal_uart_en_rx_int(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
159 {
160 unused(id);
161 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_RX, param);
162 return ERRCODE_SUCC;
163 }
164
hal_uart_en_idle_int(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)165 static errcode_t hal_uart_en_idle_int(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
166 {
167 unused(id);
168 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_CHAR_TIMEOUT, param);
169 return ERRCODE_SUCC;
170 }
171
hal_uart_en_para_err_int(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)172 static errcode_t hal_uart_en_para_err_int(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
173 {
174 unused(id);
175 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_ERROR, param);
176 return ERRCODE_SUCC;
177 }
178
hal_uart_v151_ctrl_set_attr(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)179 static errcode_t hal_uart_v151_ctrl_set_attr(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
180 {
181 unused(id);
182 hal_uart_attr_t *attr = (hal_uart_attr_t *)param;
183 hal_uart_set_data_bits(bus, attr->data_bits);
184 hal_uart_set_stop_bits(bus, attr->stop_bits);
185 hal_uart_set_parity(bus, attr->parity);
186 hal_uart_set_baud_rate(bus, attr->baud_rate, uart_port_get_clock_value(bus));
187 return ERRCODE_SUCC;
188 }
189
hal_uart_v151_ctrl_get_rxfifo_passnum(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)190 static errcode_t hal_uart_v151_ctrl_get_rxfifo_passnum(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
191 {
192 unused(id);
193 unused(bus);
194 if (param == 0) {
195 return ERRCODE_INVALID_PARAM;
196 }
197
198 uint32_t *state = (uint32_t *)param;
199 *state = 0xffffffff;
200 return ERRCODE_SUCC;
201 }
202
hal_uart_v151_ctrl_set_rxfifo_int_level(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)203 static errcode_t hal_uart_v151_ctrl_set_rxfifo_int_level(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
204 {
205 unused(id);
206 uint32_t level = (uint32_t)param;
207 if (level > (uint32_t)HAL_UART_RX_FIFO_AVAILABLE_LEVEL_LESS_2) {
208 return ERRCODE_INVALID_PARAM;
209 }
210
211 hal_uart_init_fifo(bus, (uint32_t)level, g_hal_uart_tx_fifo_level[bus]);
212 return ERRCODE_SUCC;
213 }
214
hal_uart_v151_ctrl_set_txfifo_int_level(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)215 static errcode_t hal_uart_v151_ctrl_set_txfifo_int_level(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
216 {
217 unused(id);
218 uint32_t level = (uint32_t)param;
219 if (level > (uint32_t)HAL_UART_TX_FIFO_EMPTY_LEVEL_1_2) {
220 return ERRCODE_INVALID_PARAM;
221 }
222
223 hal_uart_init_fifo(bus, g_hal_uart_rx_fifo_level[bus], (uint32_t)level);
224 return ERRCODE_SUCC;
225 }
226
hal_uart_v151_get_uart_rxfifo_threshold(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)227 static errcode_t hal_uart_v151_get_uart_rxfifo_threshold(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
228 {
229 unused(id);
230 uint32_t rx_fifo_thresh = 0;
231 uint32_t *addr = (uint32_t *)param;
232 switch (g_hal_uart_rx_fifo_level[bus]) {
233 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_EQ_1:
234 rx_fifo_thresh = 1;
235 break;
236 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4:
237 rx_fifo_thresh = (CONFIG_UART_FIFO_DEPTH >> HAL_UART_FIFO_DEPTH_SHIFT_2);
238 break;
239 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_2:
240 rx_fifo_thresh = CONFIG_UART_FIFO_DEPTH >> 1;
241 break;
242 default:
243 rx_fifo_thresh = CONFIG_UART_FIFO_DEPTH - HAL_UART_FIFO_DEPTH_MINUS_2;
244 break;
245 }
246 *addr = rx_fifo_thresh;
247 return ERRCODE_SUCC;
248 }
249
250 static const hal_uart_ctrl_t g_hal_uart_ctrl_func_array[UART_CTRL_MAX + 1] = {
251 hal_uart_v151_ctrl_set_attr, // UART_CTRL_SET_ATTR
252 NULL, // UART_CTRL_GET_ATTR
253 #if defined(CONFIG_UART_SUPPORT_TX_INT)
254 hal_uart_en_tx_int, // UART_CTRL_EN_TX_INT
255 #endif
256 hal_uart_en_rx_int, // UART_CTRL_EN_RX_INT
257 hal_uart_en_idle_int, // UART_CTRL_EN_IDLE_INT
258 hal_uart_en_para_err_int, // UART_CTRL_EN_PARITY_ERR_INT
259 hal_uart_en_para_err_int, // UART_CTRL_EN_FRAME_ERR_INT
260 hal_uart_is_tx_fifo_full, // UART_CTRL_CHECK_TX_FIFO_FULL
261 hal_uart_is_tx_fifo_empty, // UART_CTRL_CHECK_TX_BUSY
262 hal_uart_is_rx_fifo_empty, // UART_CTRL_CHECK_RX_FIFO_EMPTY
263 NULL, // UART_CTRL_FIFO_ENABLE
264 hal_uart_v151_ctrl_set_rxfifo_int_level, // UART_CTRL_SET_RX_FIFO_LEVEL
265 hal_uart_v151_ctrl_set_txfifo_int_level, // UART_CTRL_SET_TX_FIFO_LEVEL
266 NULL, // UART_CTRL_GET_REG_ADDRS
267 NULL, // UART_CTRL_TX_DMA_PROCESS
268 NULL, // UART_CTRL_FLOW_CTRL
269 NULL, // UART_CTRL_RESTORE
270 hal_uart_is_busy, // UART_CTRL_CHECK_UART_BUSY
271 hal_uart_v151_ctrl_get_rxfifo_passnum, // UART_CTRL_GET_RX_FIFO_PASSNUM
272 #if defined(CONFIG_UART_SUPPORT_LPM)
273 NULL, // UART_CTRL_SUSPEND
274 NULL, // UART_CTRL_RESUME
275 #endif
276 #if defined(CONFIG_UART_SUPPORT_DMA)
277 hal_uart_v151_get_dma_data_addr,
278 #endif
279 hal_uart_v151_get_uart_rxfifo_threshold, // get uart rx fifo threshold
280 NULL, // UART_CTRL_MAX
281 };
282
hal_uart_v151_deinit(uart_bus_t uart)283 static errcode_t hal_uart_v151_deinit(uart_bus_t uart)
284 {
285 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
286 hal_uart_rx_en(uart, false);
287 #endif
288
289 hal_uart_disable_uart(uart);
290 g_hal_uart_callback[uart] = NULL;
291 return ERRCODE_SUCC;
292 }
293
hal_uart_set_fifo_en(uart_bus_t uart,hal_uart_fifo_t fifo)294 void hal_uart_set_fifo_en(uart_bus_t uart, hal_uart_fifo_t fifo)
295 {
296 fifo_ctl_t data = (fifo_ctl_t)g_hal_uart_reg[uart]->fifo_ctl;
297 data.fifo_ctl.fifo_en = fifo;
298 g_hal_uart_reg[uart]->fifo_ctl = data.d32;
299 }
300
hal_uart_init_fifo(uart_bus_t uart,hal_uart_fifo_int_lvl_t rx_level,hal_uart_fifo_int_lvl_t tx_level)301 void hal_uart_init_fifo(uart_bus_t uart, hal_uart_fifo_int_lvl_t rx_level, hal_uart_fifo_int_lvl_t tx_level)
302 {
303 fifo_ctl_t data = (fifo_ctl_t)g_hal_uart_reg[uart]->fifo_ctl;
304 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
305 data.fifo_ctl.rx_empty_trig_h = CONFIG_UART_RX_EMPTY_TRIG_H;
306 #endif
307 data.fifo_ctl.rx_empty_trig = rx_level;
308 data.fifo_ctl.tx_empty_trig = tx_level;
309 data.fifo_ctl.fifo_en = 1;
310 g_hal_uart_reg[uart]->fifo_ctl = data.d32;
311 g_hal_uart_rx_fifo_level[uart] = rx_level;
312 g_hal_uart_tx_fifo_level[uart] = tx_level;
313 }
314
hal_uart_get_fifo_depth(uart_bus_t uart)315 uint16_t hal_uart_get_fifo_depth(uart_bus_t uart)
316 {
317 return hal_uart_get_cpr_fifo_mode(uart) * HAL_UART_FIFO_DEPTH_MULTIPLE;
318 }
319
320 /*
321 * Obtains the RX FIFO trigger level in bytes, as configured by hal_uart_set_fifo_int_levels
322 */
hal_uart_get_rx_fifo_level(uart_bus_t uart)323 uint16_t hal_uart_get_rx_fifo_level(uart_bus_t uart)
324 {
325 uint16_t fifo_depth = hal_uart_get_fifo_depth(uart);
326 switch (g_hal_uart_rx_fifo_level[uart]) {
327 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_EQ_1:
328 return 1;
329 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4:
330 return fifo_depth >> HAL_UART_FIFO_DEPTH_SHIFT_2;
331 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_2:
332 return fifo_depth >> 1;
333 case HAL_UART_RX_FIFO_AVAILABLE_LEVEL_LESS_2:
334 return fifo_depth - HAL_UART_FIFO_DEPTH_MINUS_2;
335 default:
336 break;
337 }
338 return 0;
339 }
340
hal_uart_get_data_register(uart_bus_t uart)341 volatile uint32_t *hal_uart_get_data_register(uart_bus_t uart)
342 {
343 return (volatile uint32_t *)&(g_hal_uart_reg[uart]->data);
344 }
345
hal_uart_get_error_status(uart_bus_t uart)346 uint32_t hal_uart_get_error_status(uart_bus_t uart)
347 {
348 return g_hal_uart_reg[uart]->line_status;
349 }
350
hal_uart_get_error_status_parity(uart_bus_t uart)351 bool hal_uart_get_error_status_parity(uart_bus_t uart)
352 {
353 line_status_t data = (line_status_t)g_hal_uart_reg[uart]->line_status;
354 return data.line_status.parity_err;
355 }
356
hal_uart_get_error_status_fram(uart_bus_t uart)357 bool hal_uart_get_error_status_fram(uart_bus_t uart)
358 {
359 line_status_t data = (line_status_t)g_hal_uart_reg[uart]->line_status;
360 return data.line_status.frame_err;
361 }
362
hal_uart_get_error_status_break(uart_bus_t uart)363 bool hal_uart_get_error_status_break(uart_bus_t uart)
364 {
365 line_status_t data = (line_status_t)g_hal_uart_reg[uart]->line_status;
366 return data.line_status.break_intr;
367 }
368
hal_uart_get_error_status_overrun(uart_bus_t uart)369 bool hal_uart_get_error_status_overrun(uart_bus_t uart)
370 {
371 line_status_t data = (line_status_t)g_hal_uart_reg[uart]->line_status;
372 return data.line_status.overrun_err;
373 }
374
hal_uart_set_diven(uart_bus_t uart,uint8_t val)375 static void hal_uart_set_diven(uart_bus_t uart, uint8_t val)
376 {
377 uart_ctl_t data = (uart_ctl_t)g_hal_uart_reg[uart]->uart_ctl;
378 data.uart_ctl.div_en = val;
379 g_hal_uart_reg[uart]->uart_ctl = data.d32;
380 }
381
hal_uart_set_baud_rate(uart_bus_t uart,uint32_t baud,uint32_t uart_clk)382 void hal_uart_set_baud_rate(uart_bus_t uart, uint32_t baud, uint32_t uart_clk)
383 {
384 div_fra_t div_f;
385 div_h_t div_h;
386 div_l_t div_l;
387
388 if (baud == 0) {
389 return;
390 }
391 uint16_t brd_i = uart_clk / (baud << IBRD_NEED_BAUD_OFFSET_NUM);
392 uint32_t remainder = uart_clk % (baud << REMAINDER_NEED_BAUD_OFFSET_NUM);
393 uint16_t brd_f = round_off((remainder << UART_DLF_SIZE) / (baud << IBRD_NEED_BAUD_OFFSET_NUM));
394 hal_uart_set_diven(uart, 1);
395 div_l.div_l.div_l = hal_uart_get_low_8bit(brd_i);
396 div_h.div_h.div_h = hal_uart_get_high_8bit(brd_i);
397 g_hal_uart_reg[uart]->div_l = div_l.d32;
398 g_hal_uart_reg[uart]->div_h = div_h.d32;
399 div_f.div_fra.div_fra = brd_f;
400 g_hal_uart_reg[uart]->div_fra = div_f.d32;
401 hal_uart_set_diven(uart, 0);
402 }
403
hal_uart_get_baud_rate(uart_bus_t uart,uint32_t uart_clk)404 uint32_t hal_uart_get_baud_rate(uart_bus_t uart, uint32_t uart_clk)
405 {
406 uint32_t brd_i;
407 uint32_t brd_f;
408 uint32_t baud;
409
410 hal_uart_set_diven(uart, 1);
411 brd_i = g_hal_uart_reg[uart]->div_l & (g_hal_uart_reg[uart]->div_h << HAL_UART_GET_BAUD_RATE_SHIFT);
412 brd_f = g_hal_uart_reg[uart]->div_fra;
413 hal_uart_set_diven(uart, 0);
414 /* brd_i is the integer baud divider, brd_f is fractional baud divider
415 * According to hal_uart_set_baud_rate, clock could be expressed as ((16 * baud) * brd_i + brd_f * baud / 4)
416 * so baud is (clock * 4) / (64 * brd_i + brd_f)
417 */
418 baud = (uart_clk << HAL_UART_BARD_LEFT_SHIFT_2) / (brd_i + brd_f / (1 << UART_DLF_SIZE));
419 return baud;
420 }
421
hal_uart_set_data_bits(uart_bus_t uart,hal_uart_data_bit_t bits)422 void hal_uart_set_data_bits(uart_bus_t uart, hal_uart_data_bit_t bits)
423 {
424 uart_ctl_t data = (uart_ctl_t)g_hal_uart_reg[uart]->uart_ctl;
425 data.uart_ctl.dlen = bits;
426 g_hal_uart_reg[uart]->uart_ctl = data.d32;
427 }
428
hal_uart_set_stop_bits(uart_bus_t uart,hal_uart_stop_bit_t bits)429 void hal_uart_set_stop_bits(uart_bus_t uart, hal_uart_stop_bit_t bits)
430 {
431 uart_ctl_t data = (uart_ctl_t)g_hal_uart_reg[uart]->uart_ctl;
432 data.uart_ctl.stp = bits;
433 g_hal_uart_reg[uart]->uart_ctl = data.d32;
434 }
435
hal_uart_set_parity(uart_bus_t uart,hal_uart_parity_t parity)436 void hal_uart_set_parity(uart_bus_t uart, hal_uart_parity_t parity)
437 {
438 switch (parity) {
439 case UART_PARITY_NONE:
440 hal_uart_check_en(uart, false);
441 break;
442
443 case UART_PARITY_EVEN:
444 hal_uart_check_en(uart, true);
445 hal_uart_parity_en(uart, 1);
446 break;
447
448 case UART_PARITY_ODD:
449 hal_uart_check_en(uart, true);
450 hal_uart_parity_en(uart, 0);
451 break;
452 default:
453 break;
454 }
455 }
456
hal_uart_set_ptim_en(uart_bus_t uart,bool value)457 void hal_uart_set_ptim_en(uart_bus_t uart, bool value)
458 {
459 intr_en_t data = (intr_en_t)g_hal_uart_reg[uart]->intr_en;
460 data.intr_en.ptim_en = value;
461 g_hal_uart_reg[uart]->intr_en = data.d32;
462 }
463
hal_uart_auto_flow_ctl_en(uart_bus_t bus,hal_uart_auto_flow_ctl_t auto_flow)464 void hal_uart_auto_flow_ctl_en(uart_bus_t bus, hal_uart_auto_flow_ctl_t auto_flow)
465 {
466 modem_ctl_t data = (modem_ctl_t)g_hal_uart_reg[bus]->modem_ctl;
467 data.modem_ctl.afc_en = auto_flow;
468 data.modem_ctl.rts = auto_flow;
469 g_hal_uart_reg[bus]->modem_ctl = data.d32;
470 }
471
hal_uart_enable_interrupt(uart_bus_t uart,hal_uart_interrupt_t interrupt_type,bool val)472 void hal_uart_enable_interrupt(uart_bus_t uart, hal_uart_interrupt_t interrupt_type, bool val)
473 {
474 intr_en_t inter_en = (intr_en_t)g_hal_uart_reg[uart]->intr_en;
475
476 // Perform configuration
477 switch (interrupt_type) {
478 #if defined(CONFIG_UART_SUPPORT_TX_INT)
479 case HAL_UART_INTERRUPT_TX:
480 inter_en.intr_en.tran_em_intr_en = val;
481 break;
482 #endif
483 case HAL_UART_INTERRUPT_RX:
484 case HAL_UART_INTERRUPT_CHAR_TIMEOUT:
485 inter_en.intr_en.rece_data_intr_en = val;
486 break;
487 case HAL_UART_INTERRUPT_ERROR:
488 inter_en.intr_en.rece_line_stat_intr_en = val;
489 break;
490 case HAL_UART_INTERRUPT_MODEM_STATUS:
491 inter_en.intr_en.modem_intr_en = val;
492 break;
493
494 case HAL_UART_INTERRUPT_RECEIVER_LINE_STATUS:
495 inter_en.intr_en.rece_line_stat_intr_en = val;
496 break;
497
498 default:
499 break;
500 }
501 g_hal_uart_reg[uart]->intr_en = inter_en.d32;
502 }
503
hal_uart_clear_interrupt(uart_bus_t uart,hal_uart_interrupt_t interrupt_type)504 void hal_uart_clear_interrupt(uart_bus_t uart, hal_uart_interrupt_t interrupt_type)
505 {
506 unused(interrupt_type);
507 intr_id_t data = (intr_id_t)g_hal_uart_reg[uart]->intr_id;
508 unused(data);
509 hal_uart_clear_pending(uart);
510 }
511
hal_uart_disable_uart(uart_bus_t uart)512 void hal_uart_disable_uart(uart_bus_t uart)
513 {
514 unused(uart);
515 }
516
hal_uart_is_tx_fifo_full(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)517 static errcode_t hal_uart_is_tx_fifo_full(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
518 {
519 unused(id);
520 bool *tx_fifo_full = (bool *)param;
521 fifo_status_t data = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
522 *tx_fifo_full = data.fifo_status.tx_fifo_full;
523 return ERRCODE_SUCC;
524 }
525
hal_uart_is_tx_fifo_empty(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)526 static errcode_t hal_uart_is_tx_fifo_empty(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
527 {
528 unused(id);
529 bool *tx_fifo_empty = (bool *)param;
530 fifo_status_t data = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
531 *tx_fifo_empty = data.fifo_status.tx_fifo_empty;
532 return ERRCODE_SUCC;
533 }
534
hal_uart_is_busy(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)535 static errcode_t hal_uart_is_busy(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
536 {
537 unused(id);
538 bool *uart_busy = (bool *)param;
539 fifo_status_t data = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
540 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
541 *uart_busy = data.fifo_status.uart_busy;
542 #else
543 *uart_busy = !data.fifo_status.tx_fifo_empty;
544 #endif
545 return ERRCODE_SUCC;
546 }
547
hal_uart_is_rx_fifo_full(uart_bus_t uart)548 bool hal_uart_is_rx_fifo_full(uart_bus_t uart)
549 {
550 fifo_status_t data = (fifo_status_t)g_hal_uart_reg[uart]->fifo_status;
551 return data.fifo_status.rx_fifo_full;
552 }
553
hal_uart_is_rx_fifo_empty(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)554 static errcode_t hal_uart_is_rx_fifo_empty(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
555 {
556 unused(id);
557 bool *rx_fifo_empty = (bool *)param;
558 fifo_status_t data = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
559 *rx_fifo_empty = data.fifo_status.rx_fifo_empty;
560 return ERRCODE_SUCC;
561 }
562
hal_uart_get_fifo_status(uart_bus_t uart)563 uint32_t hal_uart_get_fifo_status(uart_bus_t uart)
564 {
565 return g_hal_uart_reg[uart]->fifo_status;
566 }
567
hal_uart_force_tx_isr(uart_bus_t uart)568 void hal_uart_force_tx_isr(uart_bus_t uart)
569 {
570 g_hal_uart_force_isr_flags[uart] |= HAL_UART_FORCE_TX_ISR_FLAG;
571 uart_port_set_pending_irq(uart);
572 }
573
hal_uart_force_idle_isr(uart_bus_t uart)574 void hal_uart_force_idle_isr(uart_bus_t uart)
575 {
576 g_hal_uart_force_isr_flags[uart] |= HAL_UART_FORCE_IDLE_ISR_FLAG;
577 uart_port_set_pending_irq(uart);
578 }
579
hal_uart_check_en(uart_bus_t uart,bool val)580 void hal_uart_check_en(uart_bus_t uart, bool val)
581 {
582 uart_ctl_t data = (uart_ctl_t)g_hal_uart_reg[uart]->uart_ctl;
583 data.uart_ctl.pen = val;
584 g_hal_uart_reg[uart]->uart_ctl = data.d32;
585 }
586
hal_uart_parity_en(uart_bus_t uart,hal_uart_parity_t val)587 void hal_uart_parity_en(uart_bus_t uart, hal_uart_parity_t val)
588 {
589 uart_ctl_t data = (uart_ctl_t)(g_hal_uart_reg[uart]->uart_ctl);
590 data.uart_ctl.eps = val;
591 g_hal_uart_reg[uart]->uart_ctl = data.d32;
592 }
593
hal_uart_sir_mode_en(uart_bus_t uart,bool val)594 void hal_uart_sir_mode_en(uart_bus_t uart, bool val)
595 {
596 unused(uart);
597 unused(val);
598 }
599
hal_uart_tx_pause_en(uart_bus_t uart,bool val)600 void hal_uart_tx_pause_en(uart_bus_t uart, bool val)
601 {
602 halt_tx_t data = (halt_tx_t)g_hal_uart_reg[uart]->halt_tx;
603 data.halt_tx.halt_tx = val;
604 g_hal_uart_reg[uart]->halt_tx = data.d32;
605 }
606
hal_uart_set_baud_div(uart_bus_t uart,uint8_t val)607 void hal_uart_set_baud_div(uart_bus_t uart, uint8_t val)
608 {
609 baud_ctl_t data = (baud_ctl_t)g_hal_uart_reg[uart]->baud_ctl;
610 data.baud_ctl.baud_div = val;
611 g_hal_uart_reg[uart]->baud_ctl = data.d32;
612 }
613
hal_uart_get_baud_div(uart_bus_t uart)614 uint32_t hal_uart_get_baud_div(uart_bus_t uart)
615 {
616 baud_ctl_t data = (baud_ctl_t)g_hal_uart_reg[uart]->baud_ctl;
617 return data.baud_ctl.baud_div;
618 }
619
620 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
621 /**
622 * uart v151 pro need config rx enable to recv data.
623 */
hal_uart_rx_en(uart_bus_t uart,bool val)624 void hal_uart_rx_en(uart_bus_t uart, bool val)
625 {
626 receive_ctl_t data = (receive_ctl_t)g_hal_uart_reg[uart]->receive_ctl;
627 data.receive_ctl.receive_enable = val;
628 g_hal_uart_reg[uart]->receive_ctl = data.d32;
629 }
630
631 /**
632 * uart v151 pro use 8x sample rate of baudrate, need close low power clock.
633 * uart v151 pro use 16x sample rate of baudrate, can open low power clock.
634 */
hal_uart_set_lp_req_en(uart_bus_t uart,bool val)635 void hal_uart_set_lp_req_en(uart_bus_t uart, bool val)
636 {
637 lp_ctl_t data = (lp_ctl_t)g_hal_uart_reg[uart]->lp_ctl;
638 data.lp_ctl.lp_req_en = val;
639 g_hal_uart_reg[uart]->lp_ctl = data.d32;
640 }
641 #endif
642
643 volatile uint32_t g_test_uart_write = 1;
hal_uart_irq_handler(uart_bus_t uart)644 void hal_uart_irq_handler(uart_bus_t uart)
645 {
646 if (uart >= UART_BUS_MAX_NUM) {
647 return;
648 }
649 // Get the current register values
650
651 volatile intr_id_t uart_int_reg = (intr_id_t)g_hal_uart_reg[uart]->intr_id;
652 // Detect the interrupt cause and trigger the right callback
653 if (uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_BUSY_DETECT) {
654 #ifdef BUILD_APPLICATION_STANDARD
655 #if (USE_COMPRESS_LOG_INSTEAD_OF_SDT_LOG == YES)
656 hal_uart_print_info(0, "hal_uart_isr err: 0x%x ", ONE_ARG, uart_int_reg);
657 #endif
658 #endif
659 #if defined(CONFIG_UART_IP_VERSION_V151_PRO)
660 // read Line Status register to clear this interrupt
661 hal_uart_get_error_status(uart);
662 #endif
663 g_hal_uart_callback[uart](uart, UART_EVT_FRAME_ERR_ISR, 0);
664 }
665
666 if (uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_RX) {
667 g_hal_uart_callback[uart](uart, UART_EVT_RX_ISR, 0);
668 }
669
670 if ((uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_NO_INTERRUPT) ||
671 (uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_CHAR_TIMEOUT) ||
672 (g_hal_uart_force_isr_flags[uart] & HAL_UART_FORCE_IDLE_ISR_FLAG) != 0) {
673 g_hal_uart_callback[uart](uart, UART_EVT_IDLE_ISR, 0);
674 g_hal_uart_force_isr_flags[uart] &= ~HAL_UART_FORCE_IDLE_ISR_FLAG;
675 }
676 #if defined(CONFIG_UART_SUPPORT_TX_INT)
677 if ((uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_TX) ||
678 (g_hal_uart_force_isr_flags[uart] & HAL_UART_FORCE_TX_ISR_FLAG) != 0) {
679 // TX Interrupt
680 g_hal_uart_callback[uart](uart, UART_EVT_TX_ISR, 0);
681
682 g_hal_uart_force_isr_flags[uart] &= ~HAL_UART_FORCE_TX_ISR_FLAG;
683 }
684 #endif
685 // ERROR INTERRUPT
686 if (uart_int_reg.intr_id.intr_id == HAL_UART_INTERRUPT_RECEIVER_LINE_STATUS) {
687 // read Line Status register to clear this interrupt
688 hal_uart_get_error_status(uart);
689 g_hal_uart_callback[uart](uart, UART_EVT_OVERRUN_ERR_ISR, 0);
690 }
691 }
692
hal_uart_v151_write(uart_bus_t bus,const uint8_t * data,uint16_t len)693 static errcode_t hal_uart_v151_write(uart_bus_t bus, const uint8_t *data, uint16_t len)
694 {
695 uint8_t *data_buffer = (uint8_t *)data;
696 uint16_t length = len;
697 while (length > 0) {
698 fifo_status_t fifo_st = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
699 if (fifo_st.fifo_status.tx_fifo_full == 0) {
700 g_hal_uart_reg[bus]->data = *data_buffer++;
701 length--;
702 }
703 }
704
705 return ERRCODE_SUCC;
706 }
707
hal_uart_v151_read(uart_bus_t bus,const uint8_t * data,uint16_t len)708 static int32_t hal_uart_v151_read(uart_bus_t bus, const uint8_t *data, uint16_t len)
709 {
710 int32_t i = 0;
711 uint8_t *data_buff = (uint8_t *)data;
712
713 for (i = 0; i < len; i++) {
714 fifo_status_t fifo_status = (fifo_status_t)g_hal_uart_reg[bus]->fifo_status;
715 if (fifo_status.fifo_status.rx_fifo_empty != 0) {
716 break;
717 }
718 data_buff[i] = (uint8_t)(g_hal_uart_reg[bus]->data);
719 }
720 return i;
721 }
722
hal_uart_v151_ctrl(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)723 static errcode_t hal_uart_v151_ctrl(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
724 {
725 if (g_hal_uart_ctrl_func_array[id] != NULL) {
726 return g_hal_uart_ctrl_func_array[id](bus, id, param);
727 }
728 return ERRCODE_UART_NOT_IMPLEMENT;
729 }
730
731 #if defined(CONFIG_UART_SUPPORT_DMA)
hal_uart_v151_dma_config(uart_bus_t bus,const hal_uart_extra_attr_t * extra_attr)732 static void hal_uart_v151_dma_config(uart_bus_t bus, const hal_uart_extra_attr_t *extra_attr)
733 {
734 hal_uart_set_dmaen(bus, 0);
735 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_RECEIVER_LINE_STATUS, 1);
736 if (extra_attr->rx_dma_enable) {
737 hal_uart_set_dmaen(bus, 1);
738 hal_uart_set_fifo_en(bus, HAL_UART_FIFO_ENABLED);
739 hal_uart_init_fifo(bus, extra_attr->rx_int_threshold, extra_attr->tx_int_threshold);
740 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_RX, 0);
741 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_CHAR_TIMEOUT, 0);
742 }
743 if (extra_attr->tx_dma_enable) {
744 hal_uart_set_dmaen(bus, 1);
745 hal_uart_set_fifo_en(bus, HAL_UART_FIFO_ENABLED);
746 hal_uart_init_fifo(bus, extra_attr->rx_int_threshold, extra_attr->tx_int_threshold);
747 hal_uart_enable_interrupt(bus, HAL_UART_INTERRUPT_TX, 0);
748 }
749 }
750
751 /* only support for dma testsuit */
hal_uart_uartifls_set_rxiflsel(uart_bus_t bus,uint32_t val)752 void hal_uart_uartifls_set_rxiflsel(uart_bus_t bus, uint32_t val)
753 {
754 unused(val);
755 hal_uart_extra_attr_t extra_attr = {
756 .tx_dma_enable = 1,
757 .tx_int_threshold = HAL_UART_TX_FIFO_EMPTY_LEVEL_EQ_0,
758 .rx_dma_enable = 1,
759 .rx_int_threshold = HAL_UART_RX_FIFO_AVAILABLE_LEVEL_1_4
760 };
761 hal_uart_v151_dma_config(bus, &extra_attr);
762 }
763
764 /* only support for dma testsuit */
hal_uart_int_set(uart_bus_t bus,uint32_t reg,uint32_t int_id,uint32_t val)765 void hal_uart_int_set(uart_bus_t bus, uint32_t reg, uint32_t int_id, uint32_t val)
766 {
767 unused(bus);
768 unused(reg);
769 unused(int_id);
770 unused(val);
771 }
772
hal_uart_v151_get_dma_data_addr(uart_bus_t bus,hal_uart_ctrl_id_t id,uintptr_t param)773 static errcode_t hal_uart_v151_get_dma_data_addr(uart_bus_t bus, hal_uart_ctrl_id_t id, uintptr_t param)
774 {
775 unused(id);
776 uint32_t *addr = (uint32_t *)param;
777 *addr = (uint32_t)(uintptr_t)(&(g_hal_uart_reg[bus]->data));
778 return ERRCODE_SUCC;
779 }
780
781 #endif
782
783 static hal_uart_funcs_t g_hal_uart_v51_funcs = {
784 .init = hal_uart_v151_init,
785 .deinit = hal_uart_v151_deinit,
786 .write = hal_uart_v151_write,
787 .read = hal_uart_v151_read,
788 .ctrl = hal_uart_v151_ctrl,
789 #if defined(CONFIG_UART_SUPPORT_DMA)
790 .dma_cfg = hal_uart_v151_dma_config,
791 #endif
792 };
793
hal_uart_v151_funcs_get(void)794 hal_uart_funcs_t *hal_uart_v151_funcs_get(void)
795 {
796 return &g_hal_uart_v51_funcs;
797 }
798