• 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  *
15  * Description: Provides uart port template \n
16  *
17  * History: \n
18  * 2022-06-06, Create file. \n
19  */
20 #include "uart_porting.h"
21 #include "hal_uart_v151.h"
22 #ifdef SUPPORT_HAL_PINCTRL
23 #include "pinctrl_porting.h"
24 #include "pinctrl.h"
25 #endif
26 #include "uart.h"
27 #include "platform_core.h"
28 #include "securec.h"
29 #include "osal_interrupt.h"
30 #include "soc_osal.h"
31 #if defined(CONFIG_UART_SUPPORT_DMA)
32 #include "dma_porting.h"
33 #endif
34 
35 #ifdef CONFIG_UART_SUPPORT_PORTTING_IRQ
36 #include "interrupt_porting.h"
37 #endif
38 #ifdef LOG_SUPPORT
39 #include "log_oam_msg.h"
40 #endif
41 
42 #if !defined(BUILD_NOOSAL)
43 #if defined(USE_ALIOS)
44 #include "cmsis_os2.h"
45 #else
46 #include "cmsis_os.h"
47 #endif
48 #endif
49 
50 #define UART_BUS_0_BASE_ADDR (UART0_BASE - 4)
51 #define UART_BUS_1_BASE_ADDR (UART1_BASE - 4)
52 #define UART_BUS_2_BASE_ADDR (UART2_BASE - 4)
53 #define GPIO12_PAD_CTRL_GROUP_ADDR 0x4400D030
54 #define GPIO13_PAD_CTRL_GROUP_ADDR 0x4400D034
55 
56 #define UART_TRANS_LEN_MAX   128
57 
58 const uintptr_t g_uart_base_addrs[UART_BUS_MAX_NUM] = {
59     (uintptr_t)UART_BUS_0_BASE_ADDR,
60     (uintptr_t)UART_BUS_1_BASE_ADDR,
61     (uintptr_t)UART_BUS_2_BASE_ADDR
62 };
63 #if !defined(BUILD_NOOSAL)
64 static osal_mutex g_uart_tx_mutex[UART_BUS_MAX_NUMBER] = {0};
65 const bool g_uart_support_mutex[UART_BUS_MAX_NUMBER] = {
66     CONFIG_UART0_SUPPORT_WRITE_MUTEX,
67     CONFIG_UART1_SUPPORT_WRITE_MUTEX,
68     CONFIG_UART2_SUPPORT_WRITE_MUTEX,
69 };
70 #endif
uart_porting_base_addr_get(uart_bus_t bus)71 uintptr_t uart_porting_base_addr_get(uart_bus_t bus)
72 {
73     return g_uart_base_addrs[bus];
74 }
75 
76 typedef struct uart_interrupt {
77     core_irq_t irq_num;
78     osal_irq_handler irq_func;
79 } hal_uart_interrupt_t;
80 
81 #ifdef CONFIG_UART_SUPPORT_PORTTING_IRQ
82 static const hal_uart_interrupt_t g_uart_interrupt_lines[UART_BUS_MAX_NUMBER] = {
83 #if UART_BUS_MAX_NUMBER > 0
84     { UART_0_IRQN, (osal_irq_handler)irq_uart0_handler },
85 #endif
86 #if UART_BUS_MAX_NUMBER > 1
87     { UART_1_IRQN, (osal_irq_handler)irq_uart1_handler },
88 #endif
89 #if UART_BUS_MAX_NUMBER > 2
90     { UART_2_IRQN, (osal_irq_handler)irq_uart2_handler },
91 #endif
92 #if UART_BUS_MAX_NUMBER > 3
93     { UART_3_IRQN, (osal_irq_handler)irq_uart3_handler },
94 #endif
95 };
96 #endif
97 
uart_port_register_hal_funcs(uart_bus_t bus)98 void uart_port_register_hal_funcs(uart_bus_t bus)
99 {
100     hal_uart_register_funcs(bus, hal_uart_v151_funcs_get());
101 }
102 
103 #ifdef SUPPORT_CLOCKS_CORE
104 #include "clocks_core_common.h"
105 #endif
106 #include "debug_print.h"
107 
108 static uint32_t g_uart_clock_value = UART_CLOCK_FRQ;
109 
uart_port_set_clock_value(uart_bus_t bus,uint32_t clock)110 void uart_port_set_clock_value(uart_bus_t bus, uint32_t clock)
111 {
112     unused(bus);
113     g_uart_clock_value = clock;
114 }
115 
uart_port_get_clock_value(uart_bus_t bus)116 uint32_t uart_port_get_clock_value(uart_bus_t bus)
117 {
118 #ifdef SUPPORT_CLOCKS_CORE
119     return uart_get_clock_value(bus);
120 #else
121     UNUSED(bus);
122     return g_uart_clock_value;
123 #endif
124 }
125 
126 #define GPIO_05_SEL   0x4400d014
127 #define GPIO_06_SEL   0x4400d018
128 #define GPIO_07_SEL   0x4400d01c
129 #define GPIO_08_SEL   0x4400d020
130 #define UART_2_MODE   2
131 #define GPIO_13_SEL   0x4400d034
132 #define GPIO_14_SEL   0x4400d038
133 #define UART1_TXD_SEL 0x4400d03c
134 #define UART1_RXD_SEL 0x4400d040
135 #define UART_1_MODE   1
136 #define UART0_TXD_SEL 0x4400d044
137 #define UART0_RXD_SEL 0x4400d048
138 #define UART_0_MODE   1
uart_port_config_pinmux(uart_bus_t bus)139 void uart_port_config_pinmux(uart_bus_t bus)
140 {
141 #ifndef BOARD_ASIC
142     // uart2需要配管脚复用
143     if (bus == UART_BUS_2) {
144         uapi_reg_write32(GPIO12_PAD_CTRL_GROUP_ADDR, 0x1);
145         uapi_reg_write32(GPIO13_PAD_CTRL_GROUP_ADDR, 0x1);
146     }
147     return;
148 #else
149     if (bus == UART_BUS_2) {
150         writel(GPIO_05_SEL, UART_2_MODE);
151         writel(GPIO_06_SEL, UART_2_MODE);
152         writel(GPIO_07_SEL, UART_2_MODE);
153         writel(GPIO_08_SEL, UART_2_MODE);
154     } else if (bus == UART_BUS_1) {
155         writel(GPIO_13_SEL, UART_1_MODE);
156         writel(GPIO_14_SEL, UART_1_MODE);
157         writel(UART1_TXD_SEL, UART_1_MODE);
158         writel(UART1_RXD_SEL, UART_1_MODE);
159     } else if (bus == UART_BUS_0) {
160         writel(UART0_TXD_SEL, UART_0_MODE);
161         writel(UART0_RXD_SEL, UART_0_MODE);
162     }
163 #endif
164 #if !defined(BUILD_NOOSAL)
165     if (bus < UART_BUS_MAX_NUMBER && g_uart_support_mutex[bus] == true && g_uart_tx_mutex[bus].mutex == NULL) {
166         osal_mutex_init(&g_uart_tx_mutex[bus]);
167     }
168 #endif
169 }
170 
171 #ifdef CONFIG_UART_SUPPORT_PORTTING_IRQ
uart_port_register_irq(uart_bus_t bus)172 void uart_port_register_irq(uart_bus_t bus)
173 {
174     osal_irq_request(g_uart_interrupt_lines[bus].irq_num, g_uart_interrupt_lines[bus].irq_func, NULL, NULL, NULL);
175     osal_irq_set_priority(g_uart_interrupt_lines[bus].irq_num, irq_prio(g_uart_interrupt_lines[bus].irq_num));
176     osal_irq_enable(g_uart_interrupt_lines[bus].irq_num);
177 }
178 
irq_uart0_handler(void)179 void irq_uart0_handler(void)
180 {
181     hal_uart_irq_handler(UART_BUS_0);
182     osal_irq_clear(UART_0_IRQN);
183 }
184 
irq_uart1_handler(void)185 void irq_uart1_handler(void)
186 {
187     hal_uart_irq_handler(UART_BUS_1);
188     osal_irq_clear(UART_1_IRQN);
189 }
190 
irq_uart2_handler(void)191 void irq_uart2_handler(void)
192 {
193     hal_uart_irq_handler(UART_BUS_2);
194     osal_irq_clear(UART_2_IRQN);
195 }
196 
uart_port_unregister_irq(uart_bus_t bus)197 void uart_port_unregister_irq(uart_bus_t bus)
198 {
199     osal_irq_disable(g_uart_interrupt_lines[bus].irq_num);
200 }
201 
uart_port_set_pending_irq(uart_bus_t uart)202 void uart_port_set_pending_irq(uart_bus_t uart)
203 {
204     int_set_pendind_irq(g_uart_interrupt_lines[uart].irq_num);
205 }
206 #else
uart_port_register_irq(uart_bus_t bus)207 void uart_port_register_irq(uart_bus_t bus)
208 {
209     unused(bus);
210 }
211 
uart_port_unregister_irq(uart_bus_t bus)212 void uart_port_unregister_irq(uart_bus_t bus)
213 {
214     unused(bus);
215 }
216 #endif
217 
218 #ifdef SW_UART_DEBUG
219 #define DEBUG_UART_RX_BUFFER_SIZE 1
220 STATIC uart_bus_t g_sw_debug_uart;
221 static bool g_sw_debug_uart_enabled = false;
222 STATIC uint8_t g_uart_rx_buffer[DEBUG_UART_RX_BUFFER_SIZE];
223 
224 static void uart_rx_callback(const void *buf, uint16_t buf_len, bool remaining);
225 
uart_rx_callback(const void * buf,uint16_t buf_len,bool remaining)226 void uart_rx_callback(const void *buf, uint16_t buf_len, bool remaining)
227 {
228     UNUSED(remaining);
229     if (!g_sw_debug_uart_enabled) {
230         return;
231     }
232     uapi_uart_write(SW_DEBUG_UART_BUS, (const void *)buf, buf_len, 0);
233 }
234 
sw_debug_uart_init(uint32_t baud_rate)235 void sw_debug_uart_init(uint32_t baud_rate)
236 {
237     uart_pin_config_t uart_pins;
238     uart_attr_t uart_line_config;
239     uart_buffer_config_t uart_buffer_config;
240 
241     g_sw_debug_uart = SW_DEBUG_UART_BUS;
242     // TX configuration
243     uart_pins.tx_pin = CHIP_FIXED_TX_PIN;
244     uart_pins.rts_pin = PIN_NONE;
245 
246     // RX configuration
247     uart_pins.rx_pin = CHIP_FIXED_RX_PIN;
248     uart_pins.cts_pin = PIN_NONE;
249 
250     uart_line_config.baud_rate = baud_rate;
251     uart_line_config.data_bits = UART_DATA_BIT_8;
252     uart_line_config.parity = UART_PARITY_NONE;
253     uart_line_config.stop_bits = UART_STOP_BIT_1;
254 
255     uart_buffer_config.rx_buffer_size = DEBUG_UART_RX_BUFFER_SIZE;
256     uart_buffer_config.rx_buffer = g_uart_rx_buffer;
257 
258     (void)uapi_uart_init(SW_DEBUG_UART_BUS, &uart_pins, &uart_line_config, NULL, &uart_buffer_config);
259     uapi_uart_register_rx_callback(SW_DEBUG_UART_BUS, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
260                                    DEBUG_UART_RX_BUFFER_SIZE, uart_rx_callback);
261 
262     g_sw_debug_uart_enabled = true;
263 }
264 #ifdef ASIC_SMOKE_TEST
265 STATIC uart_bus_t g_uart2;
266 static bool g_uart2_enabled = false;
267 STATIC uint8_t g_uart2_rx_buffer[DEBUG_UART_RX_BUFFER_SIZE];
268 #define DEBUG_UART2_RX_BUFFER_SIZE 1
uart2_rx_callback(const void * buf,uint16_t buf_len,bool remaining)269 void uart2_rx_callback(const void *buf, uint16_t buf_len, bool remaining)
270 {
271     UNUSED(remaining);
272     if (!g_uart2_enabled) {
273         return;
274     }
275     uapi_uart_write(CHIP_FIXED_UART_BUS, (const void *)buf, buf_len, 0);
276 }
uart2_init(uint32_t baud_rate)277 void uart2_init(uint32_t baud_rate)
278 {
279     uart_pin_config_t uart_pins;
280     uart_attr_t uart_line_config;
281     uart_buffer_config_t uart_buffer_config;
282 
283     g_uart2 = CHIP_FIXED_UART_BUS;
284     // TX configuration
285     uart_pins.tx_pin = CHIP_FIXED_TX_PIN;
286     uart_pins.rts_pin = PIN_NONE;
287 
288     // RX configuration
289     uart_pins.rx_pin = CHIP_FIXED_RX_PIN;
290     uart_pins.cts_pin = PIN_NONE;
291 
292     uart_line_config.baud_rate = baud_rate;
293     uart_line_config.data_bits = UART_DATA_BIT_8;
294     uart_line_config.parity = UART_PARITY_NONE;
295     uart_line_config.stop_bits = UART_STOP_BIT_1;
296 
297     uart_buffer_config.rx_buffer_size = DEBUG_UART2_RX_BUFFER_SIZE;
298     uart_buffer_config.rx_buffer = g_uart2_rx_buffer;
299 
300     (void)uapi_uart_init(CHIP_FIXED_UART_BUS, &uart_pins, &uart_line_config, NULL, &uart_buffer_config);
301     uapi_uart_register_rx_callback(CHIP_FIXED_UART_BUS, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
302                                    DEBUG_UART2_RX_BUFFER_SIZE, uart2_rx_callback);
303 
304     g_uart2_enabled = true;
305 }
306 #endif
307 
308 #ifdef SW_UART_CHIP_DEFINE
UartPuts(const char * s,uint32_t len,bool is_lock)309 void UartPuts(const char *s, uint32_t len, bool is_lock)
310 {
311     if ((s == NULL) || (strlen(s) == 0)) {
312         return;
313     }
314 
315     UNUSED(is_lock);
316 #ifdef SW_UART_DEBUG
317     uapi_uart_write(SW_DEBUG_UART_BUS, (const void *)s, len, 0);
318 #elif defined(TEST_SUITE)
319     test_suite_uart_send(s);
320 #elif defined(SW_RTT_DEBUG)
321     SEGGER_RTT_Write(0, (const char *)s, len);
322 #else
323     UNUSED(s);
324     UNUSED(len);
325 #endif
326 }
327 #endif
328 
print_str_inner(const char * fmt,va_list ap)329 static void print_str_inner(const char *fmt, va_list ap)
330 {
331     int32_t len;
332     static char str_buf[UART_TRANS_LEN_MAX] = {0};
333     char *tmp_buf = NULL;
334     uint32_t buflen = UART_TRANS_LEN_MAX;
335 
336     tmp_buf = str_buf;
337     len = vsnprintf_s(tmp_buf, buflen, buflen - 1, fmt, ap);
338     if ((len == -1) && (*tmp_buf == '\0')) {
339         /* parameter is illegal or some features in fmt dont support */
340         return;
341     }
342 #ifdef CONFIG_PRINTF_BUFFER_DYNAMIC
343     const char *errmsgmalloc = "print long str, malloc failed!\n";
344     while (len == -1) {
345         /* tmp_buf is not enough */
346         if (buflen != UART_TRANS_LEN_MAX) {
347             osal_kfree(tmp_buf);
348         }
349 
350         buflen = buflen << 1;
351         tmp_buf = (char *)osal_kmalloc(buflen, OSAL_GFP_KERNEL);
352         if (tmp_buf == NULL) {
353             uapi_uart_write(SW_DEBUG_UART_BUS, (const uint8_t *)errmsgmalloc, (uint32_t)strlen(errmsgmalloc), 0);
354             return;
355         }
356         len = vsnprintf_s(tmp_buf, buflen, buflen - 1, fmt, ap);
357         if (*tmp_buf == '\0') {
358             /* parameter is illegal or some features in fmt dont support */
359             osal_kfree(tmp_buf);
360             return;
361         }
362     }
363 #endif
364     *(tmp_buf + len) = '\0';
365     uapi_uart_write(SW_DEBUG_UART_BUS, (const uint8_t *)tmp_buf, len, 0);
366 #ifdef CONFIG_PRINTF_BUFFER_DYNAMIC
367     if (buflen != UART_TRANS_LEN_MAX) {
368         osal_kfree(tmp_buf);
369     }
370 #endif
371 }
372 
print_str(const char * str,...)373 void print_str(const char *str, ...)
374 {
375     va_list args;
376     if ((str == NULL) || (strlen(str) == 0)) {
377         return;
378     }
379     va_start(args, str);
380     print_str_inner(str, args);
381     va_end(args);
382 }
383 
384 #endif
385 
386 #ifdef LOG_SUPPORT
387 /** UART Settings. Define these in the C file to avoid pulling in the UART header in the header file. */
388 #define LOG_UART_RX_MAX_BUFFER_SIZE 16
389 static uint8_t g_uart_log_rx_buffer[LOG_UART_RX_MAX_BUFFER_SIZE];
log_uart_port_init(void)390 void log_uart_port_init(void)
391 {
392     uart_pin_config_t log_uart_pins = {
393         .tx_pin = CODELOADER_UART_TX_PIN,
394         .rx_pin = CODELOADER_UART_RX_PIN,
395         .cts_pin = PIN_NONE,
396         .rts_pin = PIN_NONE
397     };
398 
399     uart_attr_t uart_line_config = {
400         .baud_rate = CONFIG_LOG_UART_BAUDRATE,
401         .data_bits = UART_DATA_BIT_8,
402         .stop_bits = UART_STOP_BIT_1,
403         .parity = UART_PARITY_NONE
404     };
405     uart_buffer_config_t uart_buffer_config;
406 
407     uart_buffer_config.rx_buffer_size = LOG_UART_RX_MAX_BUFFER_SIZE;
408     uart_buffer_config.rx_buffer = g_uart_log_rx_buffer;
409 
410     (void)uapi_uart_init(LOG_UART_BUS, &log_uart_pins, &uart_line_config, NULL, &uart_buffer_config);
411 
412 #if SYS_DEBUG_MODE_ENABLE == YES
413     uapi_uart_register_rx_callback(LOG_UART_BUS, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,
414                                    LOG_UART_RX_MAX_BUFFER_SIZE, log_uart_rx_callback);
415 #endif
416 }
417 #endif
418 
419 #ifdef CONFIG_UART_SUPPORT_PORTTING_IRQ
hal_uart_clear_pending(uart_bus_t uart)420 void hal_uart_clear_pending(uart_bus_t uart)
421 {
422     switch (uart) {
423 #if UART_BUS_MAX_NUMBER > 0
424         case UART_BUS_0:
425             osal_irq_clear(UART_0_IRQN);
426             break;
427 #endif
428 #if UART_BUS_MAX_NUMBER > 1
429         case UART_BUS_1:
430             osal_irq_clear(UART_1_IRQN);
431             break;
432 #endif
433 #if UART_BUS_MAX_NUMBER > 2
434         case UART_BUS_2:
435             osal_irq_clear(UART_2_IRQN);
436             break;
437 #endif
438 #if UART_BUS_MAX_NUMBER > 3
439         case UART_BUS_3:
440             int_clear_pending_irq(UART_3_IRQN);
441             break;
442 #endif
443         default:
444             break;
445     }
446 }
447 #endif
448 
449 #if defined(CONFIG_UART_SUPPORT_DMA)
uart_port_get_dma_trans_dest_handshaking(uart_bus_t bus)450 uint8_t uart_port_get_dma_trans_dest_handshaking(uart_bus_t bus)
451 {
452     switch (bus) {
453         case UART_BUS_0:
454             return (uint8_t)HAL_DMA_HANDSHAKING_UART_L_TX;
455         case UART_BUS_1:
456             return (uint8_t)HAL_DMA_HANDSHAKING_UART_H0_TX;
457         case UART_BUS_2:
458             return (uint8_t)HAL_DMA_HANDSHAKING_UART_H1_TX;
459         default:
460             return (uint8_t)HAL_DMA_HANDSHAKING_MAX_NUM;
461     }
462     return 0;
463 }
464 
uart_port_get_dma_trans_src_handshaking(uart_bus_t bus)465 uint8_t uart_port_get_dma_trans_src_handshaking(uart_bus_t bus)
466 {
467     switch (bus) {
468         case UART_BUS_0:
469             return (uint8_t)HAL_DMA_HANDSHAKING_UART_L_TX;
470         case UART_BUS_1:
471             return (uint8_t)HAL_DMA_HANDSHAKING_UART_H0_RX;
472         case UART_BUS_2:
473             return (uint8_t)HAL_DMA_HANDSHAKING_UART_H1_RX;
474         default:
475             return (uint8_t)HAL_DMA_HANDSHAKING_MAX_NUM;
476     }
477     return 0;
478 }
479 #endif  /* CONFIG_UART_SUPPORT_DMA */
480 
uart_porting_lock(uart_bus_t bus)481 uint32_t uart_porting_lock(uart_bus_t bus)
482 {
483 #if !defined(BUILD_NOOSAL)
484     if ((g_uart_support_mutex[bus] == true) && (osKernelGetState() == osKernelRunning) &&
485         (osal_in_interrupt() == 0)) {
486         return (uint32_t)osal_mutex_lock_timeout(&g_uart_tx_mutex[bus], OSAL_MUTEX_WAIT_FOREVER);
487     } else {
488         return 0;
489     }
490 #else
491     unused(bus);
492     return osal_irq_lock();
493 #endif
494 }
495 
uart_porting_unlock(uart_bus_t bus,uint32_t irq_sts)496 void uart_porting_unlock(uart_bus_t bus, uint32_t irq_sts)
497 {
498 #if !defined(BUILD_NOOSAL)
499     unused(irq_sts);
500     if ((g_uart_support_mutex[bus] == true) && (osKernelGetState() == osKernelRunning) &&
501         (osal_in_interrupt() == 0)) {
502         osal_mutex_unlock(&g_uart_tx_mutex[bus]);
503     }
504 #else
505     unused(bus);
506     osal_irq_restore(irq_sts);
507 #endif
508 }
509