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