/** * Video Terminal * VT100 emulated by ESP32 + TV display + LK201 keyboard * * TinTTY main sketch * by Nick Matantsev 2017 * * Original reference: VT100 emulation code written by Martin K. Schroeder * and modified by Peter Scargill. */ #define SERIAL_KBD_BAUDRATE 4800 // hardcoded LK201 baud rate #define SERIAL_KBD_RX_PIN 16 // hardcoded in Serial2 #define SERIAL_KBD_TX_PIN 17 // hardcoded in Serial2 #define SERIAL_TTY_BAUDRATE 9600 // configurable, depends on the TTY #define SERIAL_TTY_CONFIG SERIAL_8N1 // configurable, depends on the TTY #define SERIAL_TTY_RX_PIN 18 // configurable #define SERIAL_TTY_TX_PIN 19 // configurable #include #include #include "tintty.h" #define SerialTty Serial1 #define SerialKbd Serial2 #include "Keyboard.h" #include "Display.h" Display display; int16_t scrolled = 0; uint16_t make_bw_color(uint16_t color) { return ((color >> 8) | (color & 0xFF)) & 0xFF + 0xFF00; } #define FONT_W display.font_w #define FONT_H display.font_h struct tintty_display composite_display = { display.vw, // width display.vh, // height display.vw / display.font_w, // chars horizontal display.vh / display.font_h, // chars vertical // fill rect [=](int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ display.fill_rect(x*FONT_W + display.ow, y*FONT_H + display.oh, w*FONT_W, h*FONT_H, make_bw_color(color)); }, // draw pixels [=](int16_t x, int16_t y, int16_t w, int16_t h, uint16_t *pixels){ //tft.setAddrWindow(x, y, x + w - 1, y + h - 1); //tft.pushColors(pixels, w * h, 1); for (int px = 0; px < w; px++) { for (int py = 0; py < h; py++) { int i = py*w + px; //display.pixel(x + display.ow + px, y + display.oh + py, pixels[i]); //display.fill_rect(x*FONT_SCALE + display.ow + px*FONT_SCALE, y*FONT_SCALE + display.oh + py*FONT_SCALE, FONT_SCALE, FONT_SCALE, make_bw_color(pixels[i])); } } }, // print character [=](int16_t col, int16_t row, uint16_t fg_color, uint16_t bg_color, char character){ display.print_character(col, row - scrolled, make_bw_color(0), make_bw_color(0), ' '); display.print_character(col, row - scrolled, make_bw_color(fg_color), make_bw_color(bg_color), character); }, // print cursor [=](int16_t col, int16_t row, uint16_t color){ display.fill_rect(col*display.font_w + display.ow, (row+1 - scrolled)*display.font_h-1 + display.oh, display.font_w, 1, make_bw_color(color)); //display.print_character(col, row, make_bw_color(color), 0, '_'); }, // scroll [=](int16_t offset){ //tft.vertScroll(0, (ILI9341_HEIGHT - KEYBOARD_HEIGHT), offset); int16_t rows = display.vh / display.font_h; int16_t diff = (rows + offset - (scrolled % rows)) % rows; display.scroll(diff*display.font_h); scrolled += diff; } }; /** * Keyboard callbacks. */ struct tintty_keyboard lk201_keyboard = { [=]() { Serial.print(" "); SerialKbd.print((char)LK_RING_BELL); } }; void tty_keyboard_process() { // read keyboard and send it to the host if (SerialKbd.available() > 0) { int key = SerialKbd.read(); keyboard_handle_key(key); } } // buffer to test various input sequences char *test_buffer = "-- \e[1mTinTTY\e[m --\r\n"; uint8_t test_buffer_cursor = 0; void input_init() {}; void input_idle() {}; void setup() { // Debug port Serial.begin(115200); Serial.println("Running!"); // TTY host SerialTty.begin(SERIAL_TTY_BAUDRATE, SERIAL_TTY_CONFIG, SERIAL_TTY_RX_PIN, SERIAL_TTY_TX_PIN, false, 100); // LK201 keyboard connected to pins 16 and 17 SerialKbd.begin(SERIAL_KBD_BAUDRATE); display.setup(); input_init(); tintty_run( [=](){ // peek idle loop while (true) { // first peek from the test buffer if (test_buffer[test_buffer_cursor]) { return test_buffer[test_buffer_cursor]; } tty_keyboard_process(); // fall back to normal blocking serial input if (SerialTty.available() > 0) { return (char)SerialTty.peek(); } // idle logic only after peeks failed tintty_idle(&composite_display); input_idle(); } }, [=](){ while(true) { // process at least one idle loop first to allow input to happen tintty_idle(&composite_display); input_idle(); tty_keyboard_process(); // first read from the test buffer if (test_buffer[test_buffer_cursor]) { return test_buffer[test_buffer_cursor++]; } // fall back to normal blocking serial input if (SerialTty.available() > 0) { return (char)SerialTty.read(); } } }, [=](char ch){ SerialTty.print(ch); }, &composite_display, &lk201_keyboard ); } void loop() { }