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
11static 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
17static 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
29static 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
37static 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
44bool 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
67bool 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