• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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