uart: support TX
This commit is contained in:
parent
f4d22b5b16
commit
61f89b2aa7
3
board/N4
3
board/N4
|
@ -147,3 +147,6 @@ output VGA_B7
|
|||
|
||||
input PS2_CLK
|
||||
input PS2_DAT
|
||||
|
||||
output UART_TX
|
||||
input UART_RX
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <nvboard.h>
|
||||
#include <keyboard.h>
|
||||
#include <vga.h>
|
||||
#include <uart.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
40
src/uart.cpp
40
src/uart.cpp
|
@ -2,9 +2,11 @@
|
|||
#include <uart.h>
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue