1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include "mos/device/serial_console.h" |
4 | |
5 | #include "ansi_colors.h" |
6 | #include "mos/device/console.h" |
7 | |
8 | #include <mos/lib/structures/list.h> |
9 | #include <mos_string.h> |
10 | |
11 | static size_t serial_console_write(console_t *console, const char *str, size_t len) |
12 | { |
13 | serial_console_t *serial_con = container_of(console, serial_console_t, con); |
14 | return serial_device_write(device: &serial_con->device, data: str, length: len); |
15 | } |
16 | |
17 | static bool serial_console_set_color(console_t *console, standard_color_t fg, standard_color_t bg) |
18 | { |
19 | serial_console_t *serial_con = container_of(console, serial_console_t, con); |
20 | serial_con->fg = fg; |
21 | serial_con->bg = bg; |
22 | char buf[64] = { 0 }; |
23 | get_ansi_color(buf, fg, bg); |
24 | serial_device_write(device: &serial_con->device, ANSI_COLOR_RESET, length: sizeof(ANSI_COLOR_RESET) - 1); |
25 | serial_device_write(device: &serial_con->device, data: buf, length: strlen(str: buf)); |
26 | return true; |
27 | } |
28 | |
29 | static bool serial_console_get_color(console_t *console, standard_color_t *fg, standard_color_t *bg) |
30 | { |
31 | serial_console_t *serial_con = container_of(console, serial_console_t, con); |
32 | *fg = serial_con->fg; |
33 | *bg = serial_con->bg; |
34 | return true; |
35 | } |
36 | |
37 | static bool serial_console_clear(console_t *console) |
38 | { |
39 | serial_console_t *serial_con = container_of(console, serial_console_t, con); |
40 | serial_device_write(device: &serial_con->device, data: "\033[2J" , length: 4); |
41 | return true; |
42 | } |
43 | |
44 | bool serial_console_setup(console_t *console) |
45 | { |
46 | linked_list_init(list_node(console)); |
47 | |
48 | serial_console_t *const serial_con = container_of(console, serial_console_t, con); |
49 | |
50 | if (!console->ops->write) |
51 | console->ops->write = serial_console_write; |
52 | |
53 | console->caps |= CONSOLE_CAP_COLOR; |
54 | if (!console->ops->set_color) |
55 | console->ops->set_color = serial_console_set_color; |
56 | |
57 | if (!console->ops->get_color) |
58 | console->ops->get_color = serial_console_get_color; |
59 | |
60 | console->caps |= CONSOLE_CAP_CLEAR; |
61 | if (!console->ops->clear) |
62 | console->ops->clear = serial_console_clear; |
63 | |
64 | return serial_device_setup(device: &serial_con->device); |
65 | } |
66 | |
67 | bool serial_console_irq_handler(u32 irq, void *data) |
68 | { |
69 | MOS_UNUSED(irq); |
70 | |
71 | console_t *const console = (console_t *) data; |
72 | serial_console_t *const serial_con = container_of(console, serial_console_t, con); |
73 | |
74 | while (serial_dev_get_data_ready(device: &serial_con->device)) |
75 | { |
76 | char c = '\0'; |
77 | serial_device_read(device: &serial_con->device, data: &c, length: 1); |
78 | if (c == '\r') |
79 | c = '\n'; |
80 | serial_device_write(device: &serial_con->device, data: &c, length: 1); |
81 | console_putc(con: &serial_con->con, c); |
82 | } |
83 | |
84 | return true; |
85 | } |
86 | |