listen serial input and react by callback registered.
Dependents: Interference_Simple StrCommandHandler_Demo SerialInputReactionHandler_DEMO
Revision 0:ec916055f0dd, committed 2019-11-12
- Comitter:
- aktk
- Date:
- Tue Nov 12 01:10:29 2019 +0000
- Child:
- 1:fd211f137803
- Commit message:
- First Implement;
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialInputReactionHandler.cpp Tue Nov 12 01:10:29 2019 +0000 @@ -0,0 +1,141 @@ +#include "SerialInputReactionHandler.h" + +char const * const SerialInputReactionHandler::ARROW_UP = "\x1b\x5b\x41"; +char const * const SerialInputReactionHandler::ARROW_DOWN = "\x1b\x5b\x42"; +char const * const SerialInputReactionHandler::ARROW_RIGHT= "\x1b\x5b\x43"; +char const * const SerialInputReactionHandler::ARROW_LEFT = "\x1b\x5b\x44"; + +SerialInputReactionHandler::SerialInputReactionHandler( + Callback<int(char const * const)> arg_callback_onCommand +) +{ + funcIfInput[KB_SINGLE_INPUT] = &SerialInputReactionHandler::listenKBSingleInput; + funcIfInput[KB_TILL_ENTER] = &SerialInputReactionHandler::listenKBTillEnter; + callback_onCommand = arg_callback_onCommand; +} + +void SerialInputReactionHandler::attach( + Callback<int (char const * const)> arg_callback_onCommand +) +{ + callback_onCommand = arg_callback_onCommand; +} + +void SerialInputReactionHandler::startReception( + Serial * arg_serial_socket, + InputMode arg_mode +) +{ + m_serial_socket = arg_serial_socket; + m_input_mode = arg_mode; + m_serial_socket->attach(callback(this, &SerialInputReactionHandler::sig_bind)); +} + +void SerialInputReactionHandler::quit() +{ + m_serial_socket->attach(NULL); +} + +void SerialInputReactionHandler::commonProcedure() +{ +} + +void SerialInputReactionHandler::sig_bind() +{ + commonProcedure(); + (this->*funcIfInput[m_input_mode])(); +} + +void SerialInputReactionHandler::changeMode(InputMode arg_mode) +{ + discardBuffer(); + m_input_mode = arg_mode; +} + +void SerialInputReactionHandler::listenKBSingleInput() +{ + m_buffer_c = m_serial_socket->getc(); + m_buffer_s = m_buffer_c; + callback_onCommand(m_buffer_s.c_str()); + m_serial_socket->printf("Single key board input: %c (%x)\n", m_buffer_c, m_buffer_c); + discardBuffer(); +} + +bool isUpperCase (const char arg_c) +{ + return ('A' <= arg_c && arg_c <= 'Z'); +} + +bool isLowerCase (const char arg_c) +{ + return ('a' <= arg_c && arg_c <= 'z'); +} + +bool isSymbol (const char arg_c) +{ + return ((0x20 <= arg_c && arg_c <= 0x40) + || (0x5B <= arg_c && arg_c <= 0x60) + || (0x7B <= arg_c && arg_c <= 0x7E)); +} + +void SerialInputReactionHandler::listenKBTillEnter() +{ + __disable_irq(); + m_buffer_c = m_serial_socket->getc(); + + if ( isUpperCase(m_buffer_c) || isLowerCase(m_buffer_c) || isSymbol( m_buffer_c)) { + + if(m_buffer_s.length() != 0 && m_buffer_s[0] != '\0') + m_buffer_s += m_buffer_c; + else + m_buffer_s = m_buffer_c; + m_serial_socket->putc(m_buffer_c); + + } else if ( m_buffer_c == '\n' || m_buffer_c == '\r') { + + callback_onCommand(m_buffer_s.c_str()); + m_serial_socket->putc(m_buffer_c); + discardBuffer(); + + } else if (m_buffer_c == 0x1B /*ESC*/) { + + // If only 0x1B, ESC KEY should be Pressed, else some symbol sequence. + if (m_serial_socket->readable()) { + m_buffer_s += m_buffer_c; + m_buffer_c = m_serial_socket->getc(); + + // If 0x5B follows, it coul be arrow key was pressed + if (m_buffer_c == 0x5B && m_serial_socket->readable()) { + m_buffer_s += m_buffer_c; + m_buffer_c = m_serial_socket->getc(); + } + + m_buffer_s += m_buffer_c; + // Arrows + callback_onCommand(m_buffer_s.c_str()); + } + discardBuffer(); + + } else { + switch (m_buffer_c) { + case 0x08 /*BS */: + case 0x7F /*DEL*/: + m_buffer_s.erase(m_buffer_s.end() - 1); + //m_serial_socket->putc(0x7F); + m_serial_socket->putc(0x08); + m_serial_socket->putc(0x20); + m_serial_socket->putc(0x08); + break; + case 0x1B /*ESC*/: + break; + + } + } + __enable_irq(); +} + +void SerialInputReactionHandler::discardBuffer() +{ + m_buffer_c = '\0'; + m_buffer_s = ""; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialInputReactionHandler.h Tue Nov 12 01:10:29 2019 +0000 @@ -0,0 +1,59 @@ +#ifndef SERIAL_INPUT_REACTION_HANDLER_H +#define SERIAL_INPUT_REACTION_HANDLER_H + +#include "mbed.h" +#include <string> + +class SerialInputReactionHandler +{ +public: + enum InputMode {KB_SINGLE_INPUT = 0, KB_TILL_ENTER, NUMBEROFMODES}; + static char const * const ARROW_UP; + static char const * const ARROW_DOWN; + static char const * const ARROW_RIGHT; + static char const * const ARROW_LEFT; + + SerialInputReactionHandler( + Callback<int (char const * const)> arg_callback_onCommand = &echoCommand + ); + + void attach(Callback<int (char const * const)> arg_callback_onCommand); + void startReception(Serial * arg_serial_socket, InputMode arg_mode = KB_SINGLE_INPUT); + void quit(); + + void changeMode(InputMode arg_mode); + +private: + void commonProcedure(); + void listenKBSingleInput(); + void listenKBTillEnter(); + void discardBuffer(); + + void (SerialInputReactionHandler::*funcIfInput[NUMBEROFMODES])(); + + /** Wrapper function that executes commonProcedure() and a function + * listed in funcIfInput[]() + * + * This function is supposed to be used as callback attached to such like + * Serial.attach(), so that it is called evrey a key input thry keyboard + * or a byte written thru communication with like PCs. + */ + void sig_bind(); + + Callback<int (char const * const)> callback_onCommand; + static int echoCommand (char const * const); + + Serial * m_serial_socket; + + InputMode m_input_mode; + uint8_t m_buffer_c; + string m_buffer_s; +}; + +inline int SerialInputReactionHandler::echoCommand (char const * const arg_str) +{ + printf("%s", arg_str); + return 0; +} + +#endif