1 /*
2 * Copyright (c) 2019 Intel corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <ctype.h>
9 #include <kernel.h>
10 #include <device.h>
11 #include <drivers/uart.h>
12 #include <sys/__assert.h>
13 #include <tracing_core.h>
14 #include <tracing_buffer.h>
15 #include <tracing_backend.h>
16
17 static const struct device *tracing_uart_dev;
18
19 #ifdef CONFIG_TRACING_HANDLE_HOST_CMD
uart_isr(const struct device * dev,void * user_data)20 static void uart_isr(const struct device *dev, void *user_data)
21 {
22 int rx;
23 uint8_t byte;
24 static uint8_t *cmd;
25 static uint32_t length, cur;
26
27 ARG_UNUSED(user_data);
28
29 while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
30 if (!uart_irq_rx_ready(dev)) {
31 continue;
32 }
33
34 rx = uart_fifo_read(dev, &byte, 1);
35 if (rx < 0) {
36 uart_irq_rx_disable(dev);
37 return;
38 }
39
40 if (!cmd) {
41 length = tracing_cmd_buffer_alloc(&cmd);
42 }
43
44 if (!isprint(byte)) {
45 if (byte == '\r') {
46 cmd[cur] = '\0';
47 tracing_cmd_handle(cmd, cur);
48 cmd = NULL;
49 cur = 0U;
50 }
51
52 continue;
53 }
54
55 if (cur < length - 1) {
56 cmd[cur++] = byte;
57 }
58 }
59 }
60 #endif
61
tracing_backend_uart_output(const struct tracing_backend * backend,uint8_t * data,uint32_t length)62 static void tracing_backend_uart_output(
63 const struct tracing_backend *backend,
64 uint8_t *data, uint32_t length)
65 {
66 for (uint32_t i = 0; i < length; i++) {
67 uart_poll_out(tracing_uart_dev, data[i]);
68 }
69 }
70
tracing_backend_uart_init(void)71 static void tracing_backend_uart_init(void)
72 {
73 tracing_uart_dev =
74 device_get_binding(CONFIG_TRACING_BACKEND_UART_NAME);
75 __ASSERT(tracing_uart_dev, "uart backend binding failed");
76
77 #ifdef CONFIG_TRACING_HANDLE_HOST_CMD
78 uart_irq_rx_disable(tracing_uart_dev);
79 uart_irq_tx_disable(tracing_uart_dev);
80
81 uart_irq_callback_set(tracing_uart_dev, uart_isr);
82
83 while (uart_irq_rx_ready(tracing_uart_dev)) {
84 uint8_t c;
85
86 uart_fifo_read(tracing_uart_dev, &c, 1);
87 }
88
89 uart_irq_rx_enable(tracing_uart_dev);
90 #endif
91 }
92
93 const struct tracing_backend_api tracing_backend_uart_api = {
94 .init = tracing_backend_uart_init,
95 .output = tracing_backend_uart_output
96 };
97
98 TRACING_BACKEND_DEFINE(tracing_backend_uart, tracing_backend_uart_api);
99