You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.1 KiB

  1. /**
  2. * Video Terminal
  3. * VT100 emulated by ESP32 + TV display + LK201 keyboard
  4. *
  5. * TinTTY main sketch
  6. * by Nick Matantsev 2017
  7. *
  8. * Original reference: VT100 emulation code written by Martin K. Schroeder
  9. * and modified by Peter Scargill.
  10. */
  11. #include <SPI.h>
  12. #include <Adafruit_GFX.h>
  13. #include "tintty.h"
  14. #define SerialTty Serial1
  15. #define SerialKbd Serial2
  16. #include "Keyboard.h"
  17. #include "Display.h"
  18. Display display;
  19. int16_t scrolled = 0;
  20. #define FONT_SCALE 2
  21. uint16_t make_bw_color(uint16_t color) {
  22. return (color >> 8) | (color & 0xFF);
  23. }
  24. struct tintty_display ili9341_display = {
  25. display.vw,//ILI9341_WIDTH,
  26. display.vh,//(ILI9341_HEIGHT - KEYBOARD_HEIGHT),
  27. display.vw / display.font_w,//ILI9341_WIDTH / TINTTY_CHAR_WIDTH,
  28. display.vh / display.font_h,//(ILI9341_HEIGHT - KEYBOARD_HEIGHT) / TINTTY_CHAR_HEIGHT,
  29. [=](int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
  30. //tft.fillRect(x, y, w, h, color);
  31. //display.fill_rect(x*FONT_SCALE + display.ow, (y*FONT_SCALE + display.oh, w*FONT_SCALE, h*FONT_SCALE, make_bw_color(color));
  32. },
  33. [=](int16_t x, int16_t y, int16_t w, int16_t h, uint16_t *pixels){
  34. //tft.setAddrWindow(x, y, x + w - 1, y + h - 1);
  35. //tft.pushColors(pixels, w * h, 1);
  36. for (int px = 0; px < w; px++) {
  37. for (int py = 0; py < h; py++) {
  38. int i = py*w + px;
  39. //display.pixel(x + display.ow + px, y + display.oh + py, pixels[i]);
  40. //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]));
  41. }
  42. }
  43. },
  44. [=](int16_t col, int16_t row, uint16_t fg_color, uint16_t bg_color, char character){
  45. display.print_character(col, row - scrolled, make_bw_color(fg_color), make_bw_color(bg_color), character);
  46. },
  47. [=](int16_t col, int16_t row, uint16_t color){
  48. 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));
  49. //display.print_character(col, row, make_bw_color(color), 0, '_');
  50. },
  51. [=](int16_t offset){
  52. //tft.vertScroll(0, (ILI9341_HEIGHT - KEYBOARD_HEIGHT), offset);
  53. int16_t rows = display.vh / display.font_h;
  54. int16_t diff = (rows + offset - (scrolled % rows)) % rows;
  55. display.scroll(diff*display.font_h);
  56. scrolled += diff;
  57. }
  58. };
  59. void tty_keyboard_process()
  60. {
  61. // read keyboard and send it to the host
  62. if (SerialKbd.available() > 0) {
  63. int key = SerialKbd.read();
  64. keyboard_handle_key(key);
  65. }
  66. }
  67. // buffer to test various input sequences
  68. char *test_buffer = "-- \e[1mTinTTY\e[m --\r\n";
  69. uint8_t test_buffer_cursor = 0;
  70. void input_init() {};
  71. void input_idle() {};
  72. void setup() {
  73. // Debug port
  74. Serial.begin(115200);
  75. Serial.println("Running!");
  76. // TTY host
  77. SerialTty.begin(9600, SERIAL_8N1, 18, 19, false, 100);
  78. // LK201 keyboard connected to pins 16 and 17
  79. SerialKbd.begin(4800);
  80. display.setup();
  81. //uint16_t tftID = tft.readID();
  82. //tft.begin(tftID);
  83. input_init();
  84. tintty_run(
  85. [=](){
  86. // peek idle loop
  87. while (true) {
  88. // first peek from the test buffer
  89. if (test_buffer[test_buffer_cursor]) {
  90. return test_buffer[test_buffer_cursor];
  91. }
  92. tty_keyboard_process();
  93. // fall back to normal blocking serial input
  94. if (SerialTty.available() > 0) {
  95. return (char)SerialTty.peek();
  96. }
  97. // idle logic only after peeks failed
  98. tintty_idle(&ili9341_display);
  99. input_idle();
  100. }
  101. },
  102. [=](){
  103. while(true) {
  104. // process at least one idle loop first to allow input to happen
  105. tintty_idle(&ili9341_display);
  106. input_idle();
  107. tty_keyboard_process();
  108. // first read from the test buffer
  109. if (test_buffer[test_buffer_cursor]) {
  110. return test_buffer[test_buffer_cursor++];
  111. }
  112. // fall back to normal blocking serial input
  113. if (SerialTty.available() > 0) {
  114. return (char)SerialTty.read();
  115. }
  116. }
  117. },
  118. [=](char ch){ SerialTty.print(ch); },
  119. &ili9341_display
  120. );
  121. }
  122. void loop() {
  123. }