@@ -32,13 +32,15 @@ | |||||
Connect pins of your choice (A0...A8=any pins). | Connect pins of your choice (A0...A8=any pins). | ||||
Custom ladders can be used by tweaking colorMinValue and colorMaxValue | Custom ladders can be used by tweaking colorMinValue and colorMaxValue | ||||
*/ | */ | ||||
#include <ESP32Lib.h> | #include <ESP32Lib.h> | ||||
#include <Ressources/Font6x8.h> | #include <Ressources/Font6x8.h> | ||||
//#include <Ressources/CodePage437_8x8.h> | |||||
#include <Ressources/CodePage437_8x8.h> | |||||
//#include <Ressources/CodePage437_8x14.h> | //#include <Ressources/CodePage437_8x14.h> | ||||
//#include <Ressources/CodePage437_8x16.h> | //#include <Ressources/CodePage437_8x16.h> | ||||
//#include <Ressources/CodePage437_8x19.h> | //#include <Ressources/CodePage437_8x19.h> | ||||
#include <Ressources/CodePage437_9x16.h> | |||||
//#include <Ressources/CodePage437_9x16.h> | |||||
#define FONT CodePage437_8x8 | |||||
//pin configuration for DAC | //pin configuration for DAC | ||||
const int outputPin = 25; | const int outputPin = 25; | ||||
@@ -62,9 +64,8 @@ public: | |||||
int w = 365; // vw + 2*ow | int w = 365; // vw + 2*ow | ||||
int h = 275; // vh + 2*oh | int h = 275; // vh + 2*oh | ||||
#define FONT CodePage437_9x16 // for options, see the Resources includes ^^^ | |||||
int font_w = 9; | |||||
int font_h = 16; | |||||
int font_w = FONT.charWidth; | |||||
int font_h = FONT.charHeight + 1; | |||||
int cols = vw / font_w; | int cols = vw / font_w; | ||||
int rows = vh / font_h; | int rows = vh / font_h; | ||||
@@ -104,8 +105,7 @@ public: | |||||
int x = ow + col*font_w; | int x = ow + col*font_w; | ||||
int y = oh + row*font_h; | int y = oh + row*font_h; | ||||
videodisplay.setCursor(x, y); | videodisplay.setCursor(x, y); | ||||
videodisplay.frontColor = fg_color; | |||||
videodisplay.backColor = bg_color; | |||||
videodisplay.setTextColor(fg_color, bg_color); | |||||
videodisplay.print(character); | videodisplay.print(character); | ||||
} | } | ||||
@@ -1,4 +1,6 @@ | |||||
/* SOURCE: http://www.netbsd.org/docs/Hardware/Machines/DEC/lk201.html */ | /* SOURCE: http://www.netbsd.org/docs/Hardware/Machines/DEC/lk201.html */ | ||||
/* SOURCE: https://lkml.org/lkml/2004/3/16/160 */ | |||||
/* https://vt100.net/docs/vt100-ug/chapter3.html */ | |||||
/**********************************************************************/ | /**********************************************************************/ | ||||
@@ -94,6 +96,7 @@ | |||||
/* pressed. */ | /* pressed. */ | ||||
#define LK_OUTPUT_ERROR 0xb5 | |||||
#define LK_INPUT_ERROR 0xB6 /* sent by the keyboard if it receives an */ | #define LK_INPUT_ERROR 0xB6 /* sent by the keyboard if it receives an */ | ||||
/* invalid command. */ | /* invalid command. */ | ||||
@@ -103,11 +106,17 @@ | |||||
#define LK_ALLUP 0xB3 | #define LK_ALLUP 0xB3 | ||||
#define LK_ALL_KEYS_UP 0xb3 | |||||
#define LK_METRONOME 0xb4 | |||||
/**********************************************************************/ | /**********************************************************************/ | ||||
bool mod_shift = false; | bool mod_shift = false; | ||||
bool mod_ctrl = false; | bool mod_ctrl = false; | ||||
#define KB_CHAR(key_base, key_shift) c = ((mod_shift) ? (key_shift) : (key_base)); | |||||
#define KB_CHAR_SHIFT(key_base, key_shift) ((mod_shift) ? (key_shift) : (key_base)) | |||||
#define KB_CHAR_CTRL(key_base, key_ctrl) ((mod_ctrl) ? (key_ctrl) : (key_base)) | |||||
#define KB_CHAR(key_base, key_shift) c = KB_CHAR_SHIFT(key_base, key_shift); | |||||
#define KB_CHARC(key_base, key_shift, key_ctrl) c = KB_CHAR_CTRL(KB_CHAR_SHIFT(key_base, key_shift), key_ctrl); | |||||
void keyboard_handle_key(int key) | void keyboard_handle_key(int key) | ||||
{ | { | ||||
@@ -117,7 +126,7 @@ void keyboard_handle_key(int key) | |||||
case 191: KB_CHAR('`', '~'); break; // (xbf): KEY_TILDE | case 191: KB_CHAR('`', '~'); break; // (xbf): KEY_TILDE | ||||
case 192: KB_CHAR('1', '!'); break; // (xc0): KEY_TR_1 | case 192: KB_CHAR('1', '!'); break; // (xc0): KEY_TR_1 | ||||
case 193: KB_CHAR('q', 'Q'); break; // (xc1): KEY_Q | case 193: KB_CHAR('q', 'Q'); break; // (xc1): KEY_Q | ||||
case 194: KB_CHAR('a', 'A'); break; // (xc2): KEY_A | |||||
case 194: KB_CHARC('a', 'A', '\x01'); break; // (xc2): KEY_A | |||||
case 195: KB_CHAR('z', 'Z'); break; // (xc3): KEY_Z | case 195: KB_CHAR('z', 'Z'); break; // (xc3): KEY_Z | ||||
case 197: KB_CHAR('2', '@'); break; // (xc5): KEY_TR_2 | case 197: KB_CHAR('2', '@'); break; // (xc5): KEY_TR_2 | ||||
case 198: KB_CHAR('w', 'W'); break; // (xc6): KEY_W | case 198: KB_CHAR('w', 'W'); break; // (xc6): KEY_W | ||||
@@ -125,33 +134,33 @@ void keyboard_handle_key(int key) | |||||
case 200: KB_CHAR('x', 'X'); break; // (xc8): KEY_X | case 200: KB_CHAR('x', 'X'); break; // (xc8): KEY_X | ||||
case 201: KB_CHAR('<', '>'); break; // (xc9): KEY_LANGLE_RANGLE | case 201: KB_CHAR('<', '>'); break; // (xc9): KEY_LANGLE_RANGLE | ||||
case 203: KB_CHAR('3', '#'); break; // (xcb): KEY_TR_3 | case 203: KB_CHAR('3', '#'); break; // (xcb): KEY_TR_3 | ||||
case 204: KB_CHAR('e', 'E'); break; // (xcc): KEY_E | |||||
case 205: KB_CHAR('d', 'D'); break; // (xcd): KEY_D | |||||
case 206: KB_CHAR('c', 'C'); break; // (xce): KEY_C | |||||
case 204: KB_CHARC('e', 'E', '\x05'); break; // (xcc): KEY_E | |||||
case 205: KB_CHARC('d', 'D', '\x04'); break; // (xcd): KEY_D | |||||
case 206: KB_CHARC('c', 'C', '\x03'); break; // (xce): KEY_C | |||||
case 208: KB_CHAR('4', '$'); break; // (xd0): KEY_TR_4 | case 208: KB_CHAR('4', '$'); break; // (xd0): KEY_TR_4 | ||||
case 209: KB_CHAR('r', 'R'); break; // (xd1): KEY_R | case 209: KB_CHAR('r', 'R'); break; // (xd1): KEY_R | ||||
case 210: KB_CHAR('f', 'F'); break; // (xd2): KEY_F | |||||
case 210: KB_CHARC('f', 'F', '\x06'); break; // (xd2): KEY_F | |||||
case 211: KB_CHAR('v', 'V'); break; // (xd3): KEY_V | case 211: KB_CHAR('v', 'V'); break; // (xd3): KEY_V | ||||
case 212: KB_CHAR(' ', ' '); break; // (xd4): KEY_SPACE | case 212: KB_CHAR(' ', ' '); break; // (xd4): KEY_SPACE | ||||
case 214: KB_CHAR('5', '%'); break; // (xd6): KEY_TR_5 | case 214: KB_CHAR('5', '%'); break; // (xd6): KEY_TR_5 | ||||
case 215: KB_CHAR('t', 'T'); break; // (xd7): KEY_T | case 215: KB_CHAR('t', 'T'); break; // (xd7): KEY_T | ||||
case 216: KB_CHAR('g', 'G'); break; // (xd8): KEY_G | |||||
case 217: KB_CHAR('b', 'B'); break; // (xd9): KEY_B | |||||
case 216: KB_CHARC('g', 'G', '\x07'); break; // (xd8): KEY_G | |||||
case 217: KB_CHARC('b', 'B', '\x02'); break; // (xd9): KEY_B | |||||
case 219: KB_CHAR('6', '^'); break; // (xdb): KEY_TR_6 | case 219: KB_CHAR('6', '^'); break; // (xdb): KEY_TR_6 | ||||
case 220: KB_CHAR('y', 'Y'); break; // (xdc): KEY_Y | case 220: KB_CHAR('y', 'Y'); break; // (xdc): KEY_Y | ||||
case 221: KB_CHAR('h', 'H'); break; // (xdd): KEY_H | |||||
case 221: KB_CHARC('h', 'H', '\x08'); break; // (xdd): KEY_H | |||||
case 222: KB_CHAR('n', 'N'); break; // (xde): KEY_N | case 222: KB_CHAR('n', 'N'); break; // (xde): KEY_N | ||||
case 224: KB_CHAR('7', '&'); break; // (xe0): KEY_TR_7 | case 224: KB_CHAR('7', '&'); break; // (xe0): KEY_TR_7 | ||||
case 225: KB_CHAR('u', 'U'); break; // (xe1): KEY_U | case 225: KB_CHAR('u', 'U'); break; // (xe1): KEY_U | ||||
case 226: KB_CHAR('j', 'J'); break; // (xe2): KEY_J | |||||
case 226: KB_CHARC('j', 'J', '\x0A'); break; // (xe2): KEY_J | |||||
case 227: KB_CHAR('m', 'M'); break; // (xe3): KEY_M | case 227: KB_CHAR('m', 'M'); break; // (xe3): KEY_M | ||||
case 229: KB_CHAR('8', '*'); break; // (xe5): KEY_TR_8 | case 229: KB_CHAR('8', '*'); break; // (xe5): KEY_TR_8 | ||||
case 230: KB_CHAR('i', 'I'); break; // (xe6): KEY_I | |||||
case 231: KB_CHAR('k', 'K'); break; // (xe7): KEY_K | |||||
case 230: KB_CHARC('i', 'I', '\x09'); break; // (xe6): KEY_I | |||||
case 231: KB_CHARC('k', 'K', '\x0B'); break; // (xe7): KEY_K | |||||
case 232: KB_CHAR(',', '<'); break; // (xe8): KEY_COMMA | case 232: KB_CHAR(',', '<'); break; // (xe8): KEY_COMMA | ||||
case 234: KB_CHAR('9', '('); break; // (xea): KEY_TR_9 | case 234: KB_CHAR('9', '('); break; // (xea): KEY_TR_9 | ||||
case 235: KB_CHAR('o', 'O'); break; // (xeb): KEY_O | case 235: KB_CHAR('o', 'O'); break; // (xeb): KEY_O | ||||
case 236: KB_CHAR('l', 'L'); break; // (xec): KEY_L | |||||
case 236: KB_CHARC('l', 'L', '\x0C'); break; // (xec): KEY_L | |||||
case 237: KB_CHAR('.', '>'); break; // (xed): KEY_PERIOD | case 237: KB_CHAR('.', '>'); break; // (xed): KEY_PERIOD | ||||
case 239: KB_CHAR('0', ')'); break; // (xef): KEY_TR_0 | case 239: KB_CHAR('0', ')'); break; // (xef): KEY_TR_0 | ||||
case 240: KB_CHAR('p', 'P'); break; // (xf0): KEY_P | case 240: KB_CHAR('p', 'P'); break; // (xf0): KEY_P | ||||
@@ -200,7 +209,14 @@ void keyboard_handle_key(int key) | |||||
case 169: SerialTty.print("\033[B"); Serial.print("DOWN "); break; // (xa9): KEY_DOWN | case 169: SerialTty.print("\033[B"); Serial.print("DOWN "); break; // (xa9): KEY_DOWN | ||||
case 170: SerialTty.print("\033[A"); Serial.print("UP "); break; // (xaa): KEY_UP | case 170: SerialTty.print("\033[A"); Serial.print("UP "); break; // (xaa): KEY_UP | ||||
case 171: break; // (xab): KEY_R_SHIFT | case 171: break; // (xab): KEY_R_SHIFT | ||||
case 100: Serial.print("<BELL ON> "); SerialKbd.print((char)LK_BELL_ENABLE); SerialKbd.print((char)LK_PARAM_VOLUME(0x7)); break; | |||||
case 101: Serial.print("<BELL OFF> "); SerialKbd.print((char)LK_BELL_DISABLE); break; | |||||
case 102: break; // F8 | |||||
case 103: Serial.print("<LED ON WAIT> "); SerialKbd.print((char)LK_LED_ENABLE); SerialKbd.print((char)LED_WAIT); break; | |||||
case 104: Serial.print("<LED OFF WAIT> "); SerialKbd.print((char)LK_LED_DISABLE); SerialKbd.print((char)LED_WAIT); break; | |||||
case 86: SerialTty.print("\x1B"); Serial.print("<ESC> "); break; | |||||
case LK_INPUT_ERROR: Serial.print("<I-ERROR> "); break; | |||||
case LK_ALLUP: | case LK_ALLUP: | ||||
mod_shift = false; | mod_shift = false; | ||||
mod_ctrl = false; | mod_ctrl = false; | ||||
@@ -142,6 +142,56 @@ void _render(tintty_display *display) { | |||||
const uint8_t char_set = state.g4bank_char_set[state.out_char_g4bank & 0x03]; // ensure 0-3 value | const uint8_t char_set = state.g4bank_char_set[state.out_char_g4bank & 0x03]; // ensure 0-3 value | ||||
display->print_character(state.out_char_col, state.out_char_row, fg_tft_color, bg_tft_color, state.out_char); | display->print_character(state.out_char_col, state.out_char_row, fg_tft_color, bg_tft_color, state.out_char); | ||||
// line-before | |||||
// @todo detect when straddling edge of buffer | |||||
if (state.out_clear_before > 0) { | |||||
const int16_t line_before_chars = min(state.out_char_col, state.out_clear_before); | |||||
const int16_t lines_before = (state.out_clear_before - line_before_chars) / display->screen_col_count; | |||||
display->fill_rect( | |||||
(state.out_char_col - line_before_chars), | |||||
(state.out_char_row) % display->screen_row_count, // @todo deal with overflow from multiplication | |||||
line_before_chars, | |||||
1, | |||||
ANSI_COLORS[state.bg_ansi_color] | |||||
); | |||||
for (int16_t i = 0; i < lines_before; i += 1) { | |||||
display->fill_rect( | |||||
0, | |||||
(state.out_char_row - 1 - i) % display->screen_row_count, // @todo deal with overflow from multiplication | |||||
display->screen_col_count, | |||||
1, | |||||
ANSI_COLORS[state.bg_ansi_color] | |||||
); | |||||
} | |||||
} | |||||
// line-after | |||||
// @todo detect when straddling edge of buffer | |||||
if (state.out_clear_after > 0) { | |||||
const int16_t line_after_chars = min(display->screen_col_count - 1 - state.out_char_col, (int) state.out_clear_after); | |||||
const int16_t lines_after = (state.out_clear_after - line_after_chars) / display->screen_col_count; | |||||
display->fill_rect( | |||||
state.out_char_col + 1, | |||||
(state.out_char_row) % display->screen_row_count, // @todo deal with overflow from multiplication | |||||
line_after_chars, | |||||
1, | |||||
ANSI_COLORS[state.bg_ansi_color] | |||||
); | |||||
for (int16_t i = 0; i < lines_after; i += 1) { | |||||
display->fill_rect( | |||||
0, | |||||
(state.out_char_row + 1 + i) % display->screen_row_count, // @todo deal with overflow from multiplication | |||||
display->screen_col_count, | |||||
1, | |||||
ANSI_COLORS[state.bg_ansi_color] | |||||
); | |||||
} | |||||
} | |||||
// clear for next render | // clear for next render | ||||
state.out_char = 0; | state.out_char = 0; | ||||
@@ -194,12 +244,6 @@ void _render(tintty_display *display) { | |||||
} | } | ||||
} | } | ||||
void bell() { | |||||
// TODO | |||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html | |||||
// https://github.com/lbernstone/Tone32 | |||||
} | |||||
void _ensure_cursor_vscroll(tintty_display *display) { | void _ensure_cursor_vscroll(tintty_display *display) { | ||||
// move displayed window down to cover cursor | // move displayed window down to cover cursor | ||||
// @todo support scrolling up as well | // @todo support scrolling up as well | ||||
@@ -594,7 +638,8 @@ void _main( | |||||
char (*peek_char)(), | char (*peek_char)(), | ||||
char (*read_char)(), | char (*read_char)(), | ||||
void (*send_char)(char str), | void (*send_char)(char str), | ||||
tintty_display *display | |||||
tintty_display *display, | |||||
tintty_keyboard *keyboard | |||||
) { | ) { | ||||
// start in default idle state | // start in default idle state | ||||
char initial_character = read_char(); | char initial_character = read_char(); | ||||
@@ -625,7 +670,7 @@ void _main( | |||||
switch (initial_character) { | switch (initial_character) { | ||||
case '\a': | case '\a': | ||||
// bell | // bell | ||||
bell(); | |||||
keyboard->bell(); | |||||
break; | break; | ||||
case '\n': | case '\n': | ||||
// line-feed | // line-feed | ||||
@@ -694,7 +739,8 @@ void tintty_run( | |||||
char (*peek_char)(), | char (*peek_char)(), | ||||
char (*read_char)(), | char (*read_char)(), | ||||
void (*send_char)(char str), | void (*send_char)(char str), | ||||
tintty_display *display | |||||
tintty_display *display, | |||||
tintty_keyboard *keyboard | |||||
) { | ) { | ||||
// set up initial state | // set up initial state | ||||
state.cursor_col = 0; | state.cursor_col = 0; | ||||
@@ -741,7 +787,7 @@ void tintty_run( | |||||
// main read cycle | // main read cycle | ||||
while (1) { | while (1) { | ||||
_main(peek_char, read_char, send_char, display); | |||||
_main(peek_char, read_char, send_char, display, keyboard); | |||||
} | } | ||||
} | } | ||||
@@ -16,6 +16,13 @@ struct tintty_display { | |||||
void (*set_vscroll)(int16_t offset); // scroll offset for entire screen | void (*set_vscroll)(int16_t offset); // scroll offset for entire screen | ||||
}; | }; | ||||
/** | |||||
* Keyboard callbacks. | |||||
*/ | |||||
struct tintty_keyboard { | |||||
void (*bell)(); | |||||
}; | |||||
/** | /** | ||||
* Main entry point. | * Main entry point. | ||||
* Peek/read callbacks are expected to block until input is available; | * Peek/read callbacks are expected to block until input is available; | ||||
@@ -26,7 +33,8 @@ void tintty_run( | |||||
char (*peek_char)(), | char (*peek_char)(), | ||||
char (*read_char)(), | char (*read_char)(), | ||||
void (*send_char)(char str), | void (*send_char)(char str), | ||||
tintty_display *display | |||||
tintty_display *display, | |||||
tintty_keyboard *keyboard | |||||
); | ); | ||||
/** | /** | ||||
@@ -25,23 +25,25 @@ Display display; | |||||
int16_t scrolled = 0; | int16_t scrolled = 0; | ||||
#define FONT_SCALE 2 | |||||
uint16_t make_bw_color(uint16_t color) { | uint16_t make_bw_color(uint16_t color) { | ||||
return (color >> 8) | (color & 0xFF); | |||||
return ((color >> 8) | (color & 0xFF)) & 0xFF + 0xFF00; | |||||
} | } | ||||
struct tintty_display ili9341_display = { | |||||
display.vw,//ILI9341_WIDTH, | |||||
display.vh,//(ILI9341_HEIGHT - KEYBOARD_HEIGHT), | |||||
display.vw / display.font_w,//ILI9341_WIDTH / TINTTY_CHAR_WIDTH, | |||||
display.vh / display.font_h,//(ILI9341_HEIGHT - KEYBOARD_HEIGHT) / TINTTY_CHAR_HEIGHT, | |||||
#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){ | [=](int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ | ||||
//tft.fillRect(x, y, w, h, color); | |||||
//display.fill_rect(x*FONT_SCALE + display.ow, (y*FONT_SCALE + display.oh, w*FONT_SCALE, h*FONT_SCALE, make_bw_color(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){ | [=](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.setAddrWindow(x, y, x + w - 1, y + h - 1); | ||||
//tft.pushColors(pixels, w * h, 1); | //tft.pushColors(pixels, w * h, 1); | ||||
@@ -54,15 +56,19 @@ struct tintty_display ili9341_display = { | |||||
} | } | ||||
}, | }, | ||||
// print character | |||||
[=](int16_t col, int16_t row, uint16_t fg_color, uint16_t bg_color, char 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); | 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){ | [=](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.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, '_'); | //display.print_character(col, row, make_bw_color(color), 0, '_'); | ||||
}, | }, | ||||
// scroll | |||||
[=](int16_t offset){ | [=](int16_t offset){ | ||||
//tft.vertScroll(0, (ILI9341_HEIGHT - KEYBOARD_HEIGHT), offset); | //tft.vertScroll(0, (ILI9341_HEIGHT - KEYBOARD_HEIGHT), offset); | ||||
int16_t rows = display.vh / display.font_h; | int16_t rows = display.vh / display.font_h; | ||||
@@ -72,6 +78,16 @@ struct tintty_display ili9341_display = { | |||||
} | } | ||||
}; | }; | ||||
/** | |||||
* Keyboard callbacks. | |||||
*/ | |||||
struct tintty_keyboard lk201_keyboard = { | |||||
[=]() { | |||||
Serial.print("<BELL RING> "); | |||||
SerialKbd.print((char)LK_RING_BELL); | |||||
} | |||||
}; | |||||
void tty_keyboard_process() | void tty_keyboard_process() | ||||
{ | { | ||||
// read keyboard and send it to the host | // read keyboard and send it to the host | ||||
@@ -122,14 +138,14 @@ void setup() { | |||||
} | } | ||||
// idle logic only after peeks failed | // idle logic only after peeks failed | ||||
tintty_idle(&ili9341_display); | |||||
tintty_idle(&composite_display); | |||||
input_idle(); | input_idle(); | ||||
} | } | ||||
}, | }, | ||||
[=](){ | [=](){ | ||||
while(true) { | while(true) { | ||||
// process at least one idle loop first to allow input to happen | // process at least one idle loop first to allow input to happen | ||||
tintty_idle(&ili9341_display); | |||||
tintty_idle(&composite_display); | |||||
input_idle(); | input_idle(); | ||||
tty_keyboard_process(); | tty_keyboard_process(); | ||||
@@ -145,7 +161,8 @@ void setup() { | |||||
} | } | ||||
}, | }, | ||||
[=](char ch){ SerialTty.print(ch); }, | [=](char ch){ SerialTty.print(ch); }, | ||||
&ili9341_display | |||||
&composite_display, | |||||
&lk201_keyboard | |||||
); | ); | ||||
} | } | ||||