Have you tried to develop a key input feature on your small embedded platform with a serial input? It is not so easy to implement correctly because the input methodology is using a complicated protocol known as VT100. In my recent project "Natural Tiny Shell (NT-Shell)" provides VT100 compatible terminal control features for small embedded systems. However, the middleware is still large for small embedded processors such as 8-bit MCUs, 16-bit MCUs and also for small 32-bit MCUs like Cortex-M0. This "MicroShell" middleware provides a minimal terminal control for the platforms.
Diff: core/mscore.c
- Revision:
- 0:e91b984e285d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/mscore.c Sun Feb 05 03:55:01 2017 +0000 @@ -0,0 +1,194 @@ +/** + * @file mscore.c + * @author Shinichiro Nakamura (CuBeatSystems) + * =============================================================== + * MicroShell (Version 0.0.1) + * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems) + * =============================================================== + * The MIT License : https://opensource.org/licenses/MIT + * + * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "mscore.h" +#include "msconf.h" + +typedef char * MSCORE_STREAM; + +typedef struct { + MSCORE_STREAM stream; + MSCORE_ACTION action; +} MSCORE_KEYMAP; + +static const MSCORE_KEYMAP kmlist[] = { +#if MSCONF_KEYMAP_SWAP_BS_DEL + { "\x7f", MSCORE_ACTION_BS }, + { "\x1b\x5b\x33\x7e", MSCORE_ACTION_DEL }, +#else + { "\x08", MSCORE_ACTION_BS }, + { "\x7f", MSCORE_ACTION_DEL }, +#endif + { "\x09", MSCORE_ACTION_TAB }, + { "\x1b\x5b\x32\x7e", MSCORE_ACTION_INSERT }, + { "\x0d", MSCORE_ACTION_ENTER }, +#if MSCONF_KEYMAP_USE_CTRL + { "\x01", MSCORE_ACTION_CTRL_A }, + { "\x02", MSCORE_ACTION_CTRL_B }, + { "\x03", MSCORE_ACTION_CTRL_C }, + { "\x04", MSCORE_ACTION_CTRL_D }, + { "\x05", MSCORE_ACTION_CTRL_E }, + { "\x06", MSCORE_ACTION_CTRL_F }, + { "\x07", MSCORE_ACTION_CTRL_G }, + { "\x08", MSCORE_ACTION_CTRL_H }, + { "\x09", MSCORE_ACTION_CTRL_I }, + { "\x0a", MSCORE_ACTION_CTRL_J }, + { "\x0b", MSCORE_ACTION_CTRL_K }, + { "\x0c", MSCORE_ACTION_CTRL_L }, + { "\x0d", MSCORE_ACTION_CTRL_M }, + { "\x0e", MSCORE_ACTION_CTRL_N }, + { "\x0f", MSCORE_ACTION_CTRL_O }, + { "\x10", MSCORE_ACTION_CTRL_P }, + { "\x11", MSCORE_ACTION_CTRL_Q }, + { "\x12", MSCORE_ACTION_CTRL_R }, + { "\x13", MSCORE_ACTION_CTRL_S }, + { "\x14", MSCORE_ACTION_CTRL_T }, + { "\x15", MSCORE_ACTION_CTRL_U }, + { "\x16", MSCORE_ACTION_CTRL_V }, + { "\x17", MSCORE_ACTION_CTRL_W }, + { "\x18", MSCORE_ACTION_CTRL_X }, + { "\x19", MSCORE_ACTION_CTRL_Y }, + { "\x1a", MSCORE_ACTION_CTRL_Z }, +#endif +#if MSCONF_KEYMAP_USE_FUNCTION + { "\x1b\x5b\x31\x31\x7e", MSCORE_ACTION_F1 }, + { "\x1b\x5b\x31\x32\x7e", MSCORE_ACTION_F2 }, + { "\x1b\x5b\x31\x33\x7e", MSCORE_ACTION_F3 }, + { "\x1b\x5b\x31\x34\x7e", MSCORE_ACTION_F4 }, + { "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5 }, + { "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6 }, + { "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7 }, + { "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8 }, + { "\x1b\x5b\x32\x30\x7e", MSCORE_ACTION_F9 }, + { "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F10 }, + { "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F11 }, + { "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F12 }, + { "\x1b\x4f\x50", MSCORE_ACTION_F1 }, + { "\x1b\x4f\x51", MSCORE_ACTION_F2 }, + { "\x1b\x4f\x52", MSCORE_ACTION_F3 }, + { "\x1b\x4f\x53", MSCORE_ACTION_F4 }, + { "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5 }, + { "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6 }, + { "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7 }, + { "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8 }, + { "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F9 }, + { "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F10 }, + { "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F11 }, + { "\x1b\x5b\x32\x34\x7e", MSCORE_ACTION_F12 }, +#endif +#if MSCONF_KEYMAP_USE_ARROW + { "\x1b\x5b\x41", MSCORE_ACTION_ARROW_UP }, + { "\x1b\x5b\x42", MSCORE_ACTION_ARROW_DOWN }, + { "\x1b\x5b\x43", MSCORE_ACTION_ARROW_RIGHT }, + { "\x1b\x5b\x44", MSCORE_ACTION_ARROW_LEFT }, +#endif +#if MSCONF_KEYMAP_USE_HOME_END + { "\x1b\x4f\x48", MSCORE_ACTION_HOME }, + { "\x1b\x4f\x46", MSCORE_ACTION_END }, + { "\x1b[1~", MSCORE_ACTION_HOME }, + { "\x1b[4~", MSCORE_ACTION_END }, +#endif +#if MSCONF_KEYMAP_USE_PAGE + { "\x1b\x5b\x35\x7e", MSCORE_ACTION_PAGE_UP }, + { "\x1b\x5b\x36\x7e", MSCORE_ACTION_PAGE_DOWN }, +#endif +}; + +static int buf_length(char *buf) +{ + int n = 0; + while (*buf++) { + n++; + } + return n; +} + +static int buf_match(char *a, char *b, int n) +{ + int i; + for (i = 0; i < n; i++) { + if (*a++ != *b++) { + return 0; + } + } + return 1; +} + +static int buf_clear(char *buf, int n) +{ + int i; + for (i = 0; i < n; i++) { + buf[i] = 0; + } + return 1; +} + +void mscore_init(MSCORE *handle) +{ + buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE); + handle->keycnt = 0; +} + +MSCORE_ACTION mscore_push(MSCORE *handle, char c) +{ + int match = 0; + handle->keybuf[handle->keycnt++] = c; + const MSCORE_KEYMAP *p = &kmlist[0]; + const int N = sizeof(kmlist) / sizeof(kmlist[0]); + int i; + for (i = 0; i < N; i++) { + if (handle->keycnt == buf_length(p->stream)) { + if (buf_match(p->stream, handle->keybuf, handle->keycnt)) { + handle->keycnt = 0; + buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE); + return p->action; + } + } else { + if (buf_match(p->stream, handle->keybuf, handle->keycnt)) { + match = 1; + break; + } + } + p++; + } + if (!match) { + handle->keycnt = 0; + buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE); + if ((' ' <= c) && (c <= '~')) { + return MSCORE_ACTION_DISPLAYABLE; + } + } + return MSCORE_ACTION_IGNORE; +} + +