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.

Dependents:   MicroShellExample

Committer:
shintamainjp
Date:
Sun Feb 05 03:55:01 2017 +0000
Revision:
0:e91b984e285d
first commitment.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:e91b984e285d 1 /**
shintamainjp 0:e91b984e285d 2 * @file mscore.c
shintamainjp 0:e91b984e285d 3 * @author Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:e91b984e285d 4 * ===============================================================
shintamainjp 0:e91b984e285d 5 * MicroShell (Version 0.0.1)
shintamainjp 0:e91b984e285d 6 * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:e91b984e285d 7 * ===============================================================
shintamainjp 0:e91b984e285d 8 * The MIT License : https://opensource.org/licenses/MIT
shintamainjp 0:e91b984e285d 9 *
shintamainjp 0:e91b984e285d 10 * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:e91b984e285d 11 *
shintamainjp 0:e91b984e285d 12 * Permission is hereby granted, free of charge, to any person
shintamainjp 0:e91b984e285d 13 * obtaining a copy of this software and associated documentation
shintamainjp 0:e91b984e285d 14 * files (the "Software"), to deal in the Software without
shintamainjp 0:e91b984e285d 15 * restriction, including without limitation the rights to use,
shintamainjp 0:e91b984e285d 16 * copy, modify, merge, publish, distribute, sublicense, and/or
shintamainjp 0:e91b984e285d 17 * sell copies of the Software, and to permit persons to whom the
shintamainjp 0:e91b984e285d 18 * Software is furnished to do so, subject to the following
shintamainjp 0:e91b984e285d 19 * conditions:
shintamainjp 0:e91b984e285d 20 *
shintamainjp 0:e91b984e285d 21 * The above copyright notice and this permission notice shall be
shintamainjp 0:e91b984e285d 22 * included in all copies or substantial portions of the Software.
shintamainjp 0:e91b984e285d 23 *
shintamainjp 0:e91b984e285d 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
shintamainjp 0:e91b984e285d 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
shintamainjp 0:e91b984e285d 26 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
shintamainjp 0:e91b984e285d 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
shintamainjp 0:e91b984e285d 28 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
shintamainjp 0:e91b984e285d 29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
shintamainjp 0:e91b984e285d 30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
shintamainjp 0:e91b984e285d 31 * OTHER DEALINGS IN THE SOFTWARE.
shintamainjp 0:e91b984e285d 32 */
shintamainjp 0:e91b984e285d 33
shintamainjp 0:e91b984e285d 34 #include "mscore.h"
shintamainjp 0:e91b984e285d 35 #include "msconf.h"
shintamainjp 0:e91b984e285d 36
shintamainjp 0:e91b984e285d 37 typedef char * MSCORE_STREAM;
shintamainjp 0:e91b984e285d 38
shintamainjp 0:e91b984e285d 39 typedef struct {
shintamainjp 0:e91b984e285d 40 MSCORE_STREAM stream;
shintamainjp 0:e91b984e285d 41 MSCORE_ACTION action;
shintamainjp 0:e91b984e285d 42 } MSCORE_KEYMAP;
shintamainjp 0:e91b984e285d 43
shintamainjp 0:e91b984e285d 44 static const MSCORE_KEYMAP kmlist[] = {
shintamainjp 0:e91b984e285d 45 #if MSCONF_KEYMAP_SWAP_BS_DEL
shintamainjp 0:e91b984e285d 46 { "\x7f", MSCORE_ACTION_BS },
shintamainjp 0:e91b984e285d 47 { "\x1b\x5b\x33\x7e", MSCORE_ACTION_DEL },
shintamainjp 0:e91b984e285d 48 #else
shintamainjp 0:e91b984e285d 49 { "\x08", MSCORE_ACTION_BS },
shintamainjp 0:e91b984e285d 50 { "\x7f", MSCORE_ACTION_DEL },
shintamainjp 0:e91b984e285d 51 #endif
shintamainjp 0:e91b984e285d 52 { "\x09", MSCORE_ACTION_TAB },
shintamainjp 0:e91b984e285d 53 { "\x1b\x5b\x32\x7e", MSCORE_ACTION_INSERT },
shintamainjp 0:e91b984e285d 54 { "\x0d", MSCORE_ACTION_ENTER },
shintamainjp 0:e91b984e285d 55 #if MSCONF_KEYMAP_USE_CTRL
shintamainjp 0:e91b984e285d 56 { "\x01", MSCORE_ACTION_CTRL_A },
shintamainjp 0:e91b984e285d 57 { "\x02", MSCORE_ACTION_CTRL_B },
shintamainjp 0:e91b984e285d 58 { "\x03", MSCORE_ACTION_CTRL_C },
shintamainjp 0:e91b984e285d 59 { "\x04", MSCORE_ACTION_CTRL_D },
shintamainjp 0:e91b984e285d 60 { "\x05", MSCORE_ACTION_CTRL_E },
shintamainjp 0:e91b984e285d 61 { "\x06", MSCORE_ACTION_CTRL_F },
shintamainjp 0:e91b984e285d 62 { "\x07", MSCORE_ACTION_CTRL_G },
shintamainjp 0:e91b984e285d 63 { "\x08", MSCORE_ACTION_CTRL_H },
shintamainjp 0:e91b984e285d 64 { "\x09", MSCORE_ACTION_CTRL_I },
shintamainjp 0:e91b984e285d 65 { "\x0a", MSCORE_ACTION_CTRL_J },
shintamainjp 0:e91b984e285d 66 { "\x0b", MSCORE_ACTION_CTRL_K },
shintamainjp 0:e91b984e285d 67 { "\x0c", MSCORE_ACTION_CTRL_L },
shintamainjp 0:e91b984e285d 68 { "\x0d", MSCORE_ACTION_CTRL_M },
shintamainjp 0:e91b984e285d 69 { "\x0e", MSCORE_ACTION_CTRL_N },
shintamainjp 0:e91b984e285d 70 { "\x0f", MSCORE_ACTION_CTRL_O },
shintamainjp 0:e91b984e285d 71 { "\x10", MSCORE_ACTION_CTRL_P },
shintamainjp 0:e91b984e285d 72 { "\x11", MSCORE_ACTION_CTRL_Q },
shintamainjp 0:e91b984e285d 73 { "\x12", MSCORE_ACTION_CTRL_R },
shintamainjp 0:e91b984e285d 74 { "\x13", MSCORE_ACTION_CTRL_S },
shintamainjp 0:e91b984e285d 75 { "\x14", MSCORE_ACTION_CTRL_T },
shintamainjp 0:e91b984e285d 76 { "\x15", MSCORE_ACTION_CTRL_U },
shintamainjp 0:e91b984e285d 77 { "\x16", MSCORE_ACTION_CTRL_V },
shintamainjp 0:e91b984e285d 78 { "\x17", MSCORE_ACTION_CTRL_W },
shintamainjp 0:e91b984e285d 79 { "\x18", MSCORE_ACTION_CTRL_X },
shintamainjp 0:e91b984e285d 80 { "\x19", MSCORE_ACTION_CTRL_Y },
shintamainjp 0:e91b984e285d 81 { "\x1a", MSCORE_ACTION_CTRL_Z },
shintamainjp 0:e91b984e285d 82 #endif
shintamainjp 0:e91b984e285d 83 #if MSCONF_KEYMAP_USE_FUNCTION
shintamainjp 0:e91b984e285d 84 { "\x1b\x5b\x31\x31\x7e", MSCORE_ACTION_F1 },
shintamainjp 0:e91b984e285d 85 { "\x1b\x5b\x31\x32\x7e", MSCORE_ACTION_F2 },
shintamainjp 0:e91b984e285d 86 { "\x1b\x5b\x31\x33\x7e", MSCORE_ACTION_F3 },
shintamainjp 0:e91b984e285d 87 { "\x1b\x5b\x31\x34\x7e", MSCORE_ACTION_F4 },
shintamainjp 0:e91b984e285d 88 { "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5 },
shintamainjp 0:e91b984e285d 89 { "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6 },
shintamainjp 0:e91b984e285d 90 { "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7 },
shintamainjp 0:e91b984e285d 91 { "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8 },
shintamainjp 0:e91b984e285d 92 { "\x1b\x5b\x32\x30\x7e", MSCORE_ACTION_F9 },
shintamainjp 0:e91b984e285d 93 { "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F10 },
shintamainjp 0:e91b984e285d 94 { "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F11 },
shintamainjp 0:e91b984e285d 95 { "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F12 },
shintamainjp 0:e91b984e285d 96 { "\x1b\x4f\x50", MSCORE_ACTION_F1 },
shintamainjp 0:e91b984e285d 97 { "\x1b\x4f\x51", MSCORE_ACTION_F2 },
shintamainjp 0:e91b984e285d 98 { "\x1b\x4f\x52", MSCORE_ACTION_F3 },
shintamainjp 0:e91b984e285d 99 { "\x1b\x4f\x53", MSCORE_ACTION_F4 },
shintamainjp 0:e91b984e285d 100 { "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5 },
shintamainjp 0:e91b984e285d 101 { "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6 },
shintamainjp 0:e91b984e285d 102 { "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7 },
shintamainjp 0:e91b984e285d 103 { "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8 },
shintamainjp 0:e91b984e285d 104 { "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F9 },
shintamainjp 0:e91b984e285d 105 { "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F10 },
shintamainjp 0:e91b984e285d 106 { "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F11 },
shintamainjp 0:e91b984e285d 107 { "\x1b\x5b\x32\x34\x7e", MSCORE_ACTION_F12 },
shintamainjp 0:e91b984e285d 108 #endif
shintamainjp 0:e91b984e285d 109 #if MSCONF_KEYMAP_USE_ARROW
shintamainjp 0:e91b984e285d 110 { "\x1b\x5b\x41", MSCORE_ACTION_ARROW_UP },
shintamainjp 0:e91b984e285d 111 { "\x1b\x5b\x42", MSCORE_ACTION_ARROW_DOWN },
shintamainjp 0:e91b984e285d 112 { "\x1b\x5b\x43", MSCORE_ACTION_ARROW_RIGHT },
shintamainjp 0:e91b984e285d 113 { "\x1b\x5b\x44", MSCORE_ACTION_ARROW_LEFT },
shintamainjp 0:e91b984e285d 114 #endif
shintamainjp 0:e91b984e285d 115 #if MSCONF_KEYMAP_USE_HOME_END
shintamainjp 0:e91b984e285d 116 { "\x1b\x4f\x48", MSCORE_ACTION_HOME },
shintamainjp 0:e91b984e285d 117 { "\x1b\x4f\x46", MSCORE_ACTION_END },
shintamainjp 0:e91b984e285d 118 { "\x1b[1~", MSCORE_ACTION_HOME },
shintamainjp 0:e91b984e285d 119 { "\x1b[4~", MSCORE_ACTION_END },
shintamainjp 0:e91b984e285d 120 #endif
shintamainjp 0:e91b984e285d 121 #if MSCONF_KEYMAP_USE_PAGE
shintamainjp 0:e91b984e285d 122 { "\x1b\x5b\x35\x7e", MSCORE_ACTION_PAGE_UP },
shintamainjp 0:e91b984e285d 123 { "\x1b\x5b\x36\x7e", MSCORE_ACTION_PAGE_DOWN },
shintamainjp 0:e91b984e285d 124 #endif
shintamainjp 0:e91b984e285d 125 };
shintamainjp 0:e91b984e285d 126
shintamainjp 0:e91b984e285d 127 static int buf_length(char *buf)
shintamainjp 0:e91b984e285d 128 {
shintamainjp 0:e91b984e285d 129 int n = 0;
shintamainjp 0:e91b984e285d 130 while (*buf++) {
shintamainjp 0:e91b984e285d 131 n++;
shintamainjp 0:e91b984e285d 132 }
shintamainjp 0:e91b984e285d 133 return n;
shintamainjp 0:e91b984e285d 134 }
shintamainjp 0:e91b984e285d 135
shintamainjp 0:e91b984e285d 136 static int buf_match(char *a, char *b, int n)
shintamainjp 0:e91b984e285d 137 {
shintamainjp 0:e91b984e285d 138 int i;
shintamainjp 0:e91b984e285d 139 for (i = 0; i < n; i++) {
shintamainjp 0:e91b984e285d 140 if (*a++ != *b++) {
shintamainjp 0:e91b984e285d 141 return 0;
shintamainjp 0:e91b984e285d 142 }
shintamainjp 0:e91b984e285d 143 }
shintamainjp 0:e91b984e285d 144 return 1;
shintamainjp 0:e91b984e285d 145 }
shintamainjp 0:e91b984e285d 146
shintamainjp 0:e91b984e285d 147 static int buf_clear(char *buf, int n)
shintamainjp 0:e91b984e285d 148 {
shintamainjp 0:e91b984e285d 149 int i;
shintamainjp 0:e91b984e285d 150 for (i = 0; i < n; i++) {
shintamainjp 0:e91b984e285d 151 buf[i] = 0;
shintamainjp 0:e91b984e285d 152 }
shintamainjp 0:e91b984e285d 153 return 1;
shintamainjp 0:e91b984e285d 154 }
shintamainjp 0:e91b984e285d 155
shintamainjp 0:e91b984e285d 156 void mscore_init(MSCORE *handle)
shintamainjp 0:e91b984e285d 157 {
shintamainjp 0:e91b984e285d 158 buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
shintamainjp 0:e91b984e285d 159 handle->keycnt = 0;
shintamainjp 0:e91b984e285d 160 }
shintamainjp 0:e91b984e285d 161
shintamainjp 0:e91b984e285d 162 MSCORE_ACTION mscore_push(MSCORE *handle, char c)
shintamainjp 0:e91b984e285d 163 {
shintamainjp 0:e91b984e285d 164 int match = 0;
shintamainjp 0:e91b984e285d 165 handle->keybuf[handle->keycnt++] = c;
shintamainjp 0:e91b984e285d 166 const MSCORE_KEYMAP *p = &kmlist[0];
shintamainjp 0:e91b984e285d 167 const int N = sizeof(kmlist) / sizeof(kmlist[0]);
shintamainjp 0:e91b984e285d 168 int i;
shintamainjp 0:e91b984e285d 169 for (i = 0; i < N; i++) {
shintamainjp 0:e91b984e285d 170 if (handle->keycnt == buf_length(p->stream)) {
shintamainjp 0:e91b984e285d 171 if (buf_match(p->stream, handle->keybuf, handle->keycnt)) {
shintamainjp 0:e91b984e285d 172 handle->keycnt = 0;
shintamainjp 0:e91b984e285d 173 buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
shintamainjp 0:e91b984e285d 174 return p->action;
shintamainjp 0:e91b984e285d 175 }
shintamainjp 0:e91b984e285d 176 } else {
shintamainjp 0:e91b984e285d 177 if (buf_match(p->stream, handle->keybuf, handle->keycnt)) {
shintamainjp 0:e91b984e285d 178 match = 1;
shintamainjp 0:e91b984e285d 179 break;
shintamainjp 0:e91b984e285d 180 }
shintamainjp 0:e91b984e285d 181 }
shintamainjp 0:e91b984e285d 182 p++;
shintamainjp 0:e91b984e285d 183 }
shintamainjp 0:e91b984e285d 184 if (!match) {
shintamainjp 0:e91b984e285d 185 handle->keycnt = 0;
shintamainjp 0:e91b984e285d 186 buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
shintamainjp 0:e91b984e285d 187 if ((' ' <= c) && (c <= '~')) {
shintamainjp 0:e91b984e285d 188 return MSCORE_ACTION_DISPLAYABLE;
shintamainjp 0:e91b984e285d 189 }
shintamainjp 0:e91b984e285d 190 }
shintamainjp 0:e91b984e285d 191 return MSCORE_ACTION_IGNORE;
shintamainjp 0:e91b984e285d 192 }
shintamainjp 0:e91b984e285d 193
shintamainjp 0:e91b984e285d 194