uart: merge rx terminal into tx terminal

* RX should send each key directly, instead of providing cook mode
This commit is contained in:
Zihao Yu 2024-01-11 00:20:29 +08:00
parent 8179e010a6
commit d2b8a0e380
5 changed files with 43 additions and 59 deletions

View File

@ -9,7 +9,9 @@ private:
std::vector<uint8_t *> lines; std::vector<uint8_t *> lines;
int cursor_x, cursor_y; // cursor_y start with all history when scrolling is supported int cursor_x, cursor_y; // cursor_y start with all history when scrolling is supported
bool is_cursor_visible; bool is_cursor_visible;
bool is_focus;
SDL_Texture *cursor_texture; SDL_Texture *cursor_texture;
SDL_Texture *get_focus_cursor_texture;
int screen_y; int screen_y;
bool dirty_screen; bool dirty_screen;
bool *dirty_line; bool *dirty_line;
@ -32,6 +34,7 @@ public:
void feed_str(const char *s); void feed_str(const char *s);
void clear(); void clear();
void set_cursor_visibility(bool v); void set_cursor_visibility(bool v);
void set_focus(bool v);
void update_gui(); void update_gui();
}; };

View File

@ -7,14 +7,12 @@
class UART : public Component{ class UART : public Component{
private: private:
Term *tx_term, *rx_term; Term *term;
int tx_state, rx_state; int tx_state, rx_state;
uint16_t divisor; uint16_t divisor;
uint8_t tx_data, rx_data; uint8_t tx_data, rx_data;
std::string rx_input;
std::string rx_sending_str; std::string rx_sending_str;
static constexpr const char *rx_input_prompt = "(Press Enter to issue): "; bool need_update_gui;
bool tx_update_gui, rx_update_gui;
uint8_t *p_tx; uint8_t *p_tx;
public: public:
UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h); UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h);
@ -26,7 +24,7 @@ public:
void tx_receive(); void tx_receive();
void rx_send(); void rx_send();
void rx_getchar(uint8_t ch); void rx_getchar(uint8_t ch);
void rx_term_focus(bool v); void term_focus(bool v);
}; };
#endif #endif

View File

@ -4,28 +4,28 @@
extern std::vector<Component *> components; extern std::vector<Component *> components;
void uart_rx_getchar(uint8_t ch); void uart_rx_getchar(uint8_t ch);
void uart_rx_term_focus(bool v); void uart_term_focus(bool v);
void kb_push_key(uint8_t scancode, bool is_keydown); void kb_push_key(uint8_t scancode, bool is_keydown);
static bool focus_uart_rx_term = false; static bool uart_term_get_focus = false;
static void mousedown_handler(const SDL_Event &ev) { static void mousedown_handler(const SDL_Event &ev) {
int x_pos = ev.button.x; int x_pos = ev.button.x;
int y_pos = ev.button.y; int y_pos = ev.button.y;
bool click_uart_rx_term = false; bool click_uart_term = false;
for (auto i : components) { for (auto i : components) {
if (i->in_rect(x_pos, y_pos)) { if (i->in_rect(x_pos, y_pos)) {
switch (i->get_component_type()) { switch (i->get_component_type()) {
case BUTTON_TYPE: pin_poke(i->get_pin(), 1); break; case BUTTON_TYPE: pin_poke(i->get_pin(), 1); break;
case SWITCH_TYPE: pin_poke(i->get_pin(), i->get_state() ^ 1); break; case SWITCH_TYPE: pin_poke(i->get_pin(), i->get_state() ^ 1); break;
case UART_TYPE: click_uart_rx_term = true; break; case UART_TYPE: click_uart_term = true; break;
} }
} }
} }
if (focus_uart_rx_term ^ click_uart_rx_term) { if (uart_term_get_focus ^ click_uart_term) {
if (click_uart_rx_term) SDL_StartTextInput(); if (click_uart_term) SDL_StartTextInput();
else SDL_StopTextInput(); else SDL_StopTextInput();
focus_uart_rx_term = click_uart_rx_term; uart_term_get_focus = click_uart_term;
uart_rx_term_focus(focus_uart_rx_term); uart_term_focus(uart_term_get_focus);
} }
} }
@ -52,15 +52,15 @@ void read_event() {
case SDL_MOUSEBUTTONDOWN: mousedown_handler(ev); break; case SDL_MOUSEBUTTONDOWN: mousedown_handler(ev); break;
case SDL_MOUSEBUTTONUP: mouseup_handler(ev); break; case SDL_MOUSEBUTTONUP: mouseup_handler(ev); break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (focus_uart_rx_term) { if (uart_term_get_focus) {
switch (ev.key.keysym.sym) { switch (ev.key.keysym.sym) {
case SDLK_RETURN: uart_rx_getchar('\n'); break; case SDLK_RETURN: uart_rx_getchar('\n'); break;
case SDLK_BACKSPACE: uart_rx_getchar('\b'); break; case SDLK_BACKSPACE: uart_rx_getchar('\b'); break;
} }
} }
case SDL_KEYUP: case SDL_KEYUP:
if (!focus_uart_rx_term) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN); if (!uart_term_get_focus) kb_push_key(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN);
break; break;
case SDL_TEXTINPUT: if (focus_uart_rx_term) uart_rx_getchar(ev.text.text[0]); break; case SDL_TEXTINPUT: if (uart_term_get_focus) uart_rx_getchar(ev.text.text[0]); break;
} }
} }

View File

@ -8,7 +8,9 @@ Term::Term(SDL_Renderer *r, int x, int y, int w, int h):
h_in_char = region.h / CH_HEIGHT; h_in_char = region.h / CH_HEIGHT;
uint8_t *l = add_line(); uint8_t *l = add_line();
cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0x10, 0x10, 0x10); cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0x10, 0x10, 0x10);
get_focus_cursor_texture = new_texture(r, CH_WIDTH, CH_HEIGHT, 0xff, 0x00, 0xff);
is_cursor_visible = true; is_cursor_visible = true;
is_focus = false;
clear_screen(); clear_screen();
dirty_line = new bool[h_in_char]; dirty_line = new bool[h_in_char];
dirty_char = new bool[w_in_char * h_in_char]; dirty_char = new bool[w_in_char * h_in_char];
@ -35,6 +37,12 @@ void Term::set_cursor_visibility(bool v) {
if (update_cursor_gui) draw_cursor(); if (update_cursor_gui) draw_cursor();
} }
void Term::set_focus(bool v) {
bool update_cursor_gui = is_focus ^ v;
is_focus = v;
if (update_cursor_gui) draw_cursor();
}
void Term::clear() { void Term::clear() {
while (lines.size() > 1) { while (lines.size() > 1) {
delete [] lines.back(); delete [] lines.back();
@ -123,7 +131,8 @@ void Term::draw_cursor() {
rect.w = CH_WIDTH, rect.h = CH_HEIGHT; rect.w = CH_WIDTH, rect.h = CH_HEIGHT;
rect.y += CH_HEIGHT * y; rect.y += CH_HEIGHT * y;
rect.x += CH_WIDTH * x; rect.x += CH_WIDTH * x;
SDL_Texture *t = is_cursor_visible ? cursor_texture : ch2texture_term(' '); SDL_Texture *t = is_cursor_visible ? (is_focus ? get_focus_cursor_texture :
cursor_texture) : ch2texture_term(' ');
SDL_RenderCopy(renderer, t, NULL, &rect); SDL_RenderCopy(renderer, t, NULL, &rect);
set_redraw(); set_redraw();
} }

View File

@ -8,15 +8,13 @@ static UART* uart = NULL;
int16_t uart_divisor_cnt = 0; int16_t uart_divisor_cnt = 0;
bool is_uart_rx_idle = true; bool is_uart_rx_idle = true;
UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h): UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h):
Component(rend, cnt, init_val, ct), Component(rend, cnt, init_val, ct),
tx_state(0), rx_state(0), divisor(16), tx_update_gui(false) { tx_state(0), rx_state(0), divisor(16), need_update_gui(false) {
tx_term = new Term(rend, x, y, w, h); term = new Term(rend, x, y, w, h);
rx_term = new Term(rend, x, y + h + 1, w, CH_HEIGHT);
SDL_Rect *rect_ptr = new SDL_Rect; // rx terminal SDL_Rect *rect_ptr = new SDL_Rect;
*rect_ptr = (SDL_Rect){x, y + h + 1, w, CH_HEIGHT}; *rect_ptr = (SDL_Rect){x, y, w, h};
set_rect(rect_ptr, 0); set_rect(rect_ptr, 0);
uart_divisor_cnt = divisor - 1; uart_divisor_cnt = divisor - 1;
@ -24,17 +22,11 @@ UART::UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int
assert(len == 0 || len == 1); // either unbound or bound to 1 bit signal assert(len == 0 || len == 1); // either unbound or bound to 1 bit signal
p_tx = (uint8_t *)pin_array[UART_TX].ptr; p_tx = (uint8_t *)pin_array[UART_TX].ptr;
rx_term->feed_str(rx_input_prompt);
rx_term->set_cursor_visibility(false);
rx_input = "";
rx_sending_str = "";
SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0); SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0);
SDL_RenderDrawLine(rend, x, y + h, x + w, y + h); SDL_RenderDrawLine(rend, x, y + h, x + w, y + h);
SDL_RenderDrawLine(rend, x, y + h + 1 + CH_HEIGHT, x + w, y + h + 1 + CH_HEIGHT);
SDL_SetRenderDrawColor(rend, 0xff, 0xff, 0xff, 0); SDL_SetRenderDrawColor(rend, 0xff, 0xff, 0xff, 0);
rx_update_gui = true; rx_sending_str = "";
pin_poke(UART_RX, 1); pin_poke(UART_RX, 1);
} }
@ -60,8 +52,8 @@ void UART::tx_receive() {
} else if (tx_state == 9) { } else if (tx_state == 9) {
if (tx) { // stop bit if (tx) { // stop bit
tx_state = 0; tx_state = 0;
tx_term->feed_ch(tx_data); term->feed_ch(tx_data);
tx_update_gui = true; need_update_gui = true;
} }
} }
} }
@ -88,46 +80,28 @@ void UART::rx_send() {
} }
void UART::rx_getchar(uint8_t ch) { void UART::rx_getchar(uint8_t ch) {
if (ch == '\b') { rx_sending_str += ch;
if (rx_input.empty()) return; is_uart_rx_idle = false;
rx_input.pop_back();
rx_term->backspace(true);
} else {
rx_input += ch;
if (ch == '\n') {
rx_sending_str += rx_input;
is_uart_rx_idle = false;
rx_term->clear();
rx_term->feed_str(rx_input_prompt);
rx_input = "";
}
else { rx_term->feed_ch(ch); }
}
rx_update_gui = true;
} }
void UART::update_state() { void UART::update_state() {
if (tx_update_gui) { if (need_update_gui) {
static uint64_t last = 0; static uint64_t last = 0;
uint64_t now = nvboard_get_time(); uint64_t now = nvboard_get_time();
if (now - last > 1000000 / UART_TX_FPS) { if (now - last > 1000000 / UART_TX_FPS) {
last = now; last = now;
tx_update_gui = false; need_update_gui = false;
tx_term->update_gui(); term->update_gui();
} }
} }
if (rx_update_gui) {
rx_update_gui = false;
rx_term->update_gui();
}
} }
void UART::set_divisor(uint16_t d) { void UART::set_divisor(uint16_t d) {
divisor = d; divisor = d;
} }
void UART::rx_term_focus(bool v) { void UART::term_focus(bool v) {
rx_term->set_cursor_visibility(v); term->set_focus(v);
} }
static void init_render_local(SDL_Renderer *renderer) { static void init_render_local(SDL_Renderer *renderer) {
@ -173,6 +147,6 @@ void uart_rx_getchar(uint8_t ch) {
uart->rx_getchar(ch); uart->rx_getchar(ch);
} }
void uart_rx_term_focus(bool v) { void uart_term_focus(bool v) {
uart->rx_term_focus(v); uart->term_focus(v);
} }