uart: capture RX input in terminal
This commit is contained in:
parent
d06eb4811e
commit
28190b0c3e
|
@ -26,6 +26,8 @@ public:
|
|||
Term(SDL_Renderer *r, int x, int y, int w, int h);
|
||||
~Term();
|
||||
void feed_ch(uint8_t ch);
|
||||
void feed_str(const char *s);
|
||||
void clear();
|
||||
void update_gui();
|
||||
};
|
||||
|
||||
|
|
|
@ -3,14 +3,17 @@
|
|||
|
||||
#include <component.h>
|
||||
#include <term.h>
|
||||
#include <string>
|
||||
|
||||
class UART : public Component{
|
||||
private:
|
||||
Term *term;
|
||||
Term *tx_term, *rx_term;
|
||||
int state;
|
||||
uint16_t divisor;
|
||||
uint8_t data;
|
||||
bool need_update_gui;
|
||||
std::string rx_input;
|
||||
static constexpr const char *rx_input_prompt = "UART TX (Press Enter to issue): ";
|
||||
bool tx_update_gui, rx_update_gui;
|
||||
uint8_t *p_tx;
|
||||
public:
|
||||
UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h);
|
||||
|
@ -19,7 +22,8 @@ public:
|
|||
|
||||
virtual void update_gui();
|
||||
virtual void update_state();
|
||||
void check_tx();
|
||||
void tx_check();
|
||||
void rx_getchar(uint8_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <keyboard.h>
|
||||
#include <pins.h>
|
||||
#include <string>
|
||||
|
||||
extern std::vector<Component *> components;
|
||||
void uart_rx_getchar(uint8_t ch);
|
||||
|
||||
static void mousedown_handler(const SDL_Event &ev) {
|
||||
int x_pos = ev.button.x;
|
||||
|
@ -34,8 +34,6 @@ static void key_handler(uint8_t scancode, int is_keydown){
|
|||
kb->push_key(scancode, is_keydown);
|
||||
}
|
||||
|
||||
static std::string uart_rx_input = "";
|
||||
|
||||
void read_event() {
|
||||
SDL_Event ev;
|
||||
SDL_PollEvent(&ev);
|
||||
|
@ -48,11 +46,10 @@ void read_event() {
|
|||
case SDL_MOUSEBUTTONUP: mouseup_handler(ev); break;
|
||||
case SDL_KEYDOWN:
|
||||
if (ev.key.keysym.sym == SDLK_RETURN) {
|
||||
printf("get text = %s\n", uart_rx_input.c_str());
|
||||
uart_rx_input = "";
|
||||
uart_rx_getchar('\n');
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
break; //key_handler(ev.key.keysym.scancode, ev.key.type == SDL_KEYDOWN); break;
|
||||
case SDL_TEXTINPUT: uart_rx_input += ev.text.text; break;
|
||||
case SDL_TEXTINPUT: uart_rx_getchar(ev.text.text[0]); break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void nvboard_update() {
|
|||
|
||||
extern UART* uart;
|
||||
extern int16_t uart_divisor_cnt;
|
||||
if (unlikely((-- uart_divisor_cnt) < 0)) uart->check_tx();
|
||||
if (unlikely((-- uart_divisor_cnt) < 0)) uart->tx_check();
|
||||
|
||||
static uint64_t last = 0;
|
||||
static int cpf = 1; // count per frame
|
||||
|
|
16
src/term.cpp
16
src/term.cpp
|
@ -30,6 +30,18 @@ void Term::clear_screen() {
|
|||
SDL_RenderFillRect(renderer, ®ion);
|
||||
}
|
||||
|
||||
void Term::clear() {
|
||||
while (lines.size() > 1) {
|
||||
delete [] lines.back();
|
||||
lines.pop_back();
|
||||
}
|
||||
memset(lines[0], ' ', w_in_char);
|
||||
cursor_x = cursor_y = screen_y = 0;
|
||||
clear_screen();
|
||||
init_dirty(false);
|
||||
set_redraw();
|
||||
}
|
||||
|
||||
void Term::newline() {
|
||||
cursor_x = 0;
|
||||
cursor_y ++;
|
||||
|
@ -68,6 +80,10 @@ void Term::feed_ch(uint8_t ch) {
|
|||
if (cursor_x == w_in_char) newline();
|
||||
}
|
||||
|
||||
void Term::feed_str(const char *s) {
|
||||
while (*s != '\0') feed_ch(*(s ++));
|
||||
}
|
||||
|
||||
bool Term::is_cursor_on_screen() {
|
||||
return cursor_y >= screen_y && cursor_y < screen_y + h_in_char;
|
||||
}
|
||||
|
|
53
src/uart.cpp
53
src/uart.cpp
|
@ -7,25 +7,30 @@
|
|||
UART* uart = NULL;
|
||||
int16_t uart_divisor_cnt = 0;
|
||||
|
||||
|
||||
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),
|
||||
state(0), divisor(16), need_update_gui(false) {
|
||||
term = new Term(rend, x, y, w, h);
|
||||
state(0), divisor(16), tx_update_gui(false) {
|
||||
tx_term = new Term(rend, x, y, w, h);
|
||||
rx_term = new Term(rend, x, y + h, w, 20);
|
||||
uart_divisor_cnt = divisor - 1;
|
||||
int len = pin_array[UART_TX].vector_len;
|
||||
assert(len == 0 || len == 1); // either unbound or bound to 1 bit signal
|
||||
p_tx = (uint8_t *)pin_array[UART_TX].ptr;
|
||||
|
||||
rx_term->feed_str(rx_input_prompt);
|
||||
rx_input = "";
|
||||
rx_update_gui = true;
|
||||
}
|
||||
|
||||
UART::~UART() {
|
||||
SDL_DestroyTexture(get_texture(0));
|
||||
}
|
||||
|
||||
void UART::update_gui() {
|
||||
term->update_gui();
|
||||
void UART::update_gui() { // everything is done in update_state()
|
||||
}
|
||||
|
||||
void UART::check_tx() {
|
||||
void UART::tx_check() {
|
||||
uart_divisor_cnt = divisor - 1;
|
||||
|
||||
uint8_t tx = *p_tx;
|
||||
|
@ -38,24 +43,42 @@ void UART::check_tx() {
|
|||
data = (tx << 7) | (data >> 1); // data bit
|
||||
state ++;
|
||||
} else if (state == 9) {
|
||||
if (tx) {
|
||||
term->feed_ch(data);
|
||||
if (tx) { // stop bit
|
||||
state = 0;
|
||||
need_update_gui = true;
|
||||
} // stop bit
|
||||
tx_term->feed_ch(data);
|
||||
tx_update_gui = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UART::rx_getchar(uint8_t ch) {
|
||||
if (ch == '\n') {
|
||||
printf("Get RX input = %s\n", rx_input.c_str());
|
||||
rx_term->clear();
|
||||
rx_term->feed_str(rx_input_prompt);
|
||||
rx_input = "";
|
||||
}
|
||||
else {
|
||||
rx_input += ch;
|
||||
rx_term->feed_ch(ch);
|
||||
}
|
||||
rx_update_gui = true;
|
||||
}
|
||||
|
||||
void UART::update_state() {
|
||||
if (need_update_gui) {
|
||||
if (tx_update_gui) {
|
||||
static uint64_t last = 0;
|
||||
uint64_t now = nvboard_get_time();
|
||||
if (now - last > 1000000 / UART_TX_FPS) {
|
||||
last = now;
|
||||
need_update_gui = false;
|
||||
update_gui();
|
||||
tx_update_gui = false;
|
||||
tx_term->update_gui();
|
||||
}
|
||||
}
|
||||
if (rx_update_gui) {
|
||||
rx_update_gui = false;
|
||||
rx_term->update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
void UART::set_divisor(uint16_t d) {
|
||||
|
@ -66,9 +89,13 @@ void init_uart(SDL_Renderer *renderer) {
|
|||
int x = WINDOW_WIDTH / 2, y = 0, w = WINDOW_WIDTH / 2, h = WINDOW_HEIGHT / 2;
|
||||
uart = new UART(renderer, 1, 0, UART_TYPE, x, y, w, h);
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){x, y, w, h};
|
||||
*rect_ptr = (SDL_Rect){x, y + h, w, 10};
|
||||
uart->set_rect(rect_ptr, 0);
|
||||
uart->add_pin(UART_TX);
|
||||
uart->add_pin(UART_RX);
|
||||
add_component(uart);
|
||||
}
|
||||
|
||||
void uart_rx_getchar(uint8_t ch) {
|
||||
uart->rx_getchar(ch);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue