FabGL
ESP32 Display Controller and Graphics Library
VGA/AnsiTerminal/AnsiTerminal.ino

Serial VT/ANSI Terminal

/*
Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
Copyright (c) 2019-2022 Fabrizio Di Vittorio.
All rights reserved.
* Please contact fdivitto2013@gmail.com if you need a commercial license.
* This library and related software is available under GPL v3.
FabGL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FabGL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FabGL. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Credits:
- Guido Lehwalder, https://github.com/guidol70 : using USB-serial Port for ANSI-Terminal (https://github.com/fdivitto/FabGL/issues/110)
*/
#include "fabgl.h"
fabgl::PS2Controller PS2Controller;
fabgl::Terminal Terminal;
// notes about GPIO 2 and 12
// - GPIO2: may cause problem on programming. GPIO2 must also be either left unconnected/floating, or driven Low, in order to enter the serial bootloader.
// In normal boot mode (GPIO0 high), GPIO2 is ignored.
// - GPIO12: should be avoided. It selects flash voltage. To use it disable GPIO12 detection setting efuses with:
// python espefuse.py --port /dev/cu.SLAB_USBtoUART set_flash_voltage 3.3V
// WARN!! Good for ESP32 with 3.3V voltage (ESP-WROOM-32). This will BRICK your ESP32 if the flash isn't 3.3V
// NOTE1: replace "/dev/cu.SLAB_USBtoUART" with your serial port
// NOTE2: espefuse.py is downloadable from https://github.com/espressif/esptool
// UART Pins for USB serial
#define UART_URX 3
#define UART_UTX 1
// UART Pins for normal serial Port
#define UART_SRX 34
#define UART_STX 2
// RTS/CTS hardware flow gpios
#define RTS 13
#define CTS 35
#define RESET_PIN 12
#define RESET_PIN_ACTIVE 1
#define USERESETPIN 1
//*/
/*
#define RESET_PIN 39
#define RESET_PIN_ACTIVE 0
#define USERESETPIN 0
//*/
#include "confdialog.h"
void setup()
{
//Serial.begin(115200); delay(500); Serial.write("\n\nReset\n\n"); // DEBUG ONLY
disableCore0WDT();
delay(100); // experienced crashes without this delay!
disableCore1WDT();
// more stack is required for the UI (used inside Terminal.onVirtualKey)
Terminal.keyboardReaderTaskStackSize = 3000;
Terminal.inputQueueSize = 2048; // 2048 good to pass vttest
preferences.begin("AnsiTerminal", false);
ConfDialogApp::checkVersion();
#if USERESETPIN
pinMode(RESET_PIN, INPUT);
if (digitalRead(RESET_PIN) == RESET_PIN_ACTIVE)
preferences.clear();
#endif
// because mouse is optional, don't re-try if it is not found (to speed-up boot)
// keyboard configured on port 0, and optionally mouse on port 1
PS2Controller.begin(PS2Preset::KeyboardPort0_MousePort1);
ConfDialogApp::setupDisplay();
ConfDialogApp::loadConfiguration();
//Terminal.setLogStream(Serial); // debug only
Terminal.clear();
Terminal.enableCursor(true);
if (ConfDialogApp::getBootInfo() == BOOTINFO_ENABLED) {
Terminal.write("* * FabGL - Serial Terminal * *\r\n");
Terminal.write("* * 2019-2022 by Fabrizio Di Vittorio - www.fabgl.com * *\r\n\n");
Terminal.printf("Version : %d.%d\r\n", TERMVERSION_MAJ, TERMVERSION_MIN);
Terminal.printf("Screen Size : %d x %d\r\n", DisplayController->getScreenWidth(), DisplayController->getScreenHeight());
Terminal.printf("Terminal Size : %d x %d\r\n", Terminal.getColumns(), Terminal.getRows());
Terminal.printf("Keyboard Layout : %s\r\n", PS2Controller.keyboard()->isKeyboardAvailable() ? SupportedLayouts::names()[ConfDialogApp::getKbdLayoutIndex()] : "No Keyboard");
//Terminal.printf("Mouse : %s\r\n", PS2Controller.mouse()->isMouseAvailable() ? "Yes" : "No");
Terminal.printf("Terminal Type : %s\r\n", SupportedTerminals::names()[(int)ConfDialogApp::getTermType()]);
//Terminal.printf("Free Memory : %d bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_32BIT));
if (ConfDialogApp::getSerCtl() == SERCTL_ENABLED)
Terminal.printf("Serial Port : USB RX-Pin[%d] TX-Pin[%d]\r\n", UART_URX, UART_UTX);
else
Terminal.printf("Serial Port : Serial RX-Pin[%d] TX-Pin[%d]\r\n", UART_SRX, UART_STX);
Terminal.printf("Serial Parameters : %s\r\n", ConfDialogApp::getSerParamStr());
Terminal.write("\r\nPress F12 to change terminal configuration and CTRL-ALT-F12 to reset settings\r\n\n");
} else if (ConfDialogApp::getBootInfo() == BOOTINFO_TEMPDISABLED) {
preferences.putInt(PREF_BOOTINFO, BOOTINFO_ENABLED);
}
// onVirtualKey is triggered whenever a key is pressed or released
Terminal.onVirtualKeyItem = [&](VirtualKeyItem * vkItem) {
if (vkItem->vk == VirtualKey::VK_F12) {
if (vkItem->CTRL && (vkItem->LALT || vkItem->RALT)) {
Terminal.deactivate();
preferences.clear();
// show reboot dialog
auto rebootApp = new RebootDialogApp;
rebootApp->run(DisplayController);
} else if (!vkItem->CTRL && !vkItem->LALT && !vkItem->RALT && !vkItem->down) {
// releasing F12 key to open configuration dialog
Terminal.deactivate();
PS2Controller.mouse()->emptyQueue(); // avoid previous mouse movements to be showed on UI
auto dlgApp = new ConfDialogApp;
dlgApp->run(DisplayController);
auto progToInstall = dlgApp->progToInstall;
delete dlgApp;
Terminal.activate();
// it has been requested to install a demo program?
if (progToInstall > -1)
installProgram(progToInstall);
vkItem->vk = VirtualKey::VK_NONE;
}
}
};
// onUserSequence is triggered whenever a User Sequence has been received (ESC + '_#' ... '$'), where '...' is sent here
Terminal.onUserSequence = [&](char const * seq) {
// 'R': change resolution (for example: ESC + "_#R512x384x64$")
for (int i = 0; i < RESOLUTIONS_COUNT; ++i)
if (strcmp(RESOLUTIONS_CMDSTR[i], seq) == 0) {
// found resolution string
preferences.putInt(PREF_TEMPRESOLUTION, i);
if (ConfDialogApp::getBootInfo() == BOOTINFO_ENABLED)
preferences.putInt(PREF_BOOTINFO, BOOTINFO_TEMPDISABLED);
ESP.restart();
}
};
}
void loop()
{
// the job is done using UART interrupts
vTaskDelete(NULL);
}
int getScreenHeight()
Determines the screen height in pixels.
int getScreenWidth()
Determines the screen width in pixels.
Represents the base abstract class for bitmapped display controllers.
bool isKeyboardAvailable()
Checks if keyboard has been detected and correctly initialized.
Definition: keyboard.h:165
void emptyVirtualKeyQueue()
Empties the virtual keys queue.
Definition: keyboard.cpp:722
void emptyQueue()
Empties the mouse status and events queue.
Definition: mouse.cpp:386
static void quickCheckHardware()
Disable re-try when a mouse is not found.
Definition: mouse.h:373
static Mouse * mouse()
Returns the instance of Mouse object automatically created by PS2Controller.
static Keyboard * keyboard()
Returns the instance of Keyboard object automatically created by PS2Controller.
static void begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO=GPIO_UNUSED, gpio_num_t port1_datGPIO=GPIO_UNUSED)
Initializes PS2 device controller.
The PS2 device controller class.
Definition: ps2controller.h:82
int getRows()
Returns the number of lines.
Definition: terminal.h:1215
void clear(bool moveCursor=true)
Clears the screen.
Definition: terminal.cpp:1001
int getColumns()
Returns the number of columns.
Definition: terminal.h:1208
static int keyboardReaderTaskStackSize
Stack size of the task that reads keys from keyboard and send ANSI/VT codes to output stream in Termi...
Definition: terminal.h:1526
size_t write(const uint8_t *buffer, size_t size)
Sends specified number of codes to the display.
Definition: terminal.cpp:1950
void deactivate()
Deactivates this terminal.
Definition: terminal.cpp:290
Keyboard * keyboard()
Gets associated keyboard object.
Definition: terminal.h:1363
static int inputQueueSize
Number of characters the terminal can "write" without pause (increase if you have loss of characters ...
Definition: terminal.h:1508
void activate(TerminalTransition transition=TerminalTransition::None)
Activates this terminal for input and output.
Definition: terminal.cpp:215
void enableCursor(bool value)
Enables or disables cursor.
Definition: terminal.cpp:1106
Delegate< VirtualKeyItem * > onVirtualKeyItem
Delegate called whenever a new virtual key is received from keyboard, including shift states.
Definition: terminal.h:1484
Delegate< char const * > onUserSequence
Delegate called whenever a new user sequence has been received.
Definition: terminal.h:1494
An ANSI-VT100 compatible display terminal.
Definition: terminal.h:953
This file is the all in one include file. Application can just include this file to use FabGL library...
@ VK_F12
Definition: fabutils.h:1234
@ VK_NONE
Definition: fabutils.h:1055