From 61f89b2aa7dda7287e559161964b8801d2498968 Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Thu, 4 Jan 2024 02:50:08 +0800 Subject: [PATCH] uart: support TX --- board/N4 | 3 +++ include/uart.h | 5 +++++ src/nvboard.cpp | 5 +++++ src/term.cpp | 1 - src/uart.cpp | 40 ++++++++++++++++++++++++++++++---------- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/board/N4 b/board/N4 index 6b1caec..7fd3a97 100644 --- a/board/N4 +++ b/board/N4 @@ -147,3 +147,6 @@ output VGA_B7 input PS2_CLK input PS2_DAT + +output UART_TX +input UART_RX diff --git a/include/uart.h b/include/uart.h index e6dceef..ec0154c 100644 --- a/include/uart.h +++ b/include/uart.h @@ -7,9 +7,14 @@ class UART : public Component{ private: Term *term; + int state; + uint16_t divisor; + uint16_t divisor_cnt; + uint8_t data; public: UART(SDL_Renderer *rend, int cnt, int init_val, int ct, int x, int y, int w, int h); ~UART(); + void set_divisor(uint16_t d); virtual void update_gui(); virtual void update_state(); diff --git a/src/nvboard.cpp b/src/nvboard.cpp index 0b27a91..234643e 100644 --- a/src/nvboard.cpp +++ b/src/nvboard.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,10 @@ void nvboard_update() { extern bool is_kb_idle; if (!is_kb_idle) kb->update_state(); + extern UART* uart; + extern bool is_uart_idle; + if (!(is_uart_idle && pin_peek(UART_TX))) uart->update_state(); + static uint64_t last = 0; static uint32_t cpf = 0; // count per frame static uint32_t cnt = 0; diff --git a/src/term.cpp b/src/term.cpp index 9a21e7b..22d7493 100644 --- a/src/term.cpp +++ b/src/term.cpp @@ -9,7 +9,6 @@ Term::Term(SDL_Renderer *r, int x, int y, int w, int h): w_in_char = region.w / 10; h_in_char = region.h / 16; uint8_t *l = new_line(); - memset(l, 'a', w_in_char); cursor_texture = new_texture(r, 10, 16, 0x10, 0x10, 0x10); } diff --git a/src/uart.cpp b/src/uart.cpp index cce722e..5138688 100644 --- a/src/uart.cpp +++ b/src/uart.cpp @@ -2,9 +2,11 @@ #include UART* uart = NULL; +bool is_uart_idle = true; 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), + state(0), divisor(16), divisor_cnt(1) { term = new Term(rend, x, y, w, h); } @@ -17,15 +19,33 @@ void UART::update_gui() { } void UART::update_state() { - static int i = 0; - i ++; - if (i < 10) return; - i = 0; - static uint8_t ch = ' '; - ch += 1; - if (ch == 128) ch = ' '; - term->feed_ch(ch); - update_gui(); + if (divisor_cnt < divisor) { + divisor_cnt ++; + return; + } + divisor_cnt = 1; + + uint8_t tx = pin_peek(UART_TX); + if (state == 0) { // idle + if (!tx) { // start bit + data = 0; + is_uart_idle = false; + state ++; + } + } else if (state >= 1 && state <= 8) { // data + data = (tx << 7) | (data >> 1); // data bit + state ++; + } else if (state == 9) { + if (tx) { + term->feed_ch(data); update_gui(); + state = 0; + is_uart_idle = true; + } // stop bit + } +} + +void UART::set_divisor(uint16_t d) { + divisor = d; } void init_uart(SDL_Renderer *renderer) {