//////////////////////////////////////////////////////////////////////////////// /*! @file CommandParser.c MSDN command parser. - Part of the MSDN firmware. - Part of the Research Assistant project. - Copyright(C) 2016, Viktor E. Bursian, St.Petersburg, Russia. Viktor.Bursian@mail.ioffe.ru */////////////////////////////////////////////////////////////////////////////// #include "CommandParser.h" #include "Microsin_USB_IO.h" #include "zakavych.h" const char * const DeviceName = ZAKAVYCH(MSDN_SHORTNAME); const char * const BuildDate = __DATE__; void ProcessReceivedByte (const int16_t received_byte) { static uint8_t ParserStage = 0; //!< Parser stages: //!< - 0 - command char expected; //!< - 1 to 8 - argument digit or [CR]LF expected; //!< - 9 - got command and 8 digits, //!< [CR]LF expected; //!< - 0xD0 - got command and CR, LF expected; //!< - 0xDn - got command, n digits and CR, //!< LF expected; //!< - 0xEn - got command, n digits and [CR]LF, //!< to be executed; //!< - 0xF0 - sintax error encounted, LF expected. //!< - 0xFF - sintax error encounted, got LF, //!< now, error to be reported. static char Command = ' '; static uint8_t Argument8 = 0; static uint16_t Argument16 = 0; static uint32_t Argument32 = 0; int8_t ErrNo; switch( ParserStage ){ case 0: if( (0x21 <= received_byte) && (received_byte <= 0x7F) ){ Command = received_byte; Argument8 = 0; ParserStage = 1; }else if( received_byte == 0x0A ){ ParserStage = 0xFF; }else{ ParserStage = 0xF0; } break; case 1: case 2: if( received_byte == 0x0D ){ ParserStage += 0xCF; // -1 + 0xD0 }else if( received_byte == 0x0A ){ ParserStage += 0xDF; // -1 + 0xE0 }else{ ParserStage++; if ((received_byte >= 0x41) && (received_byte <= 0x46) ){ Argument8 = (Argument8 << 4) + (received_byte - 0x40 + 0x09); }else if( (received_byte >= 0x61) && (received_byte <= 0x66) ){ Argument8 = (Argument8 << 4) + (received_byte - 0x60 + 0x09); }else if( (received_byte >= 0x30) && (received_byte <= 0x39) ){ Argument8 = (Argument8 << 4) + (received_byte - 0x30); }else{ ParserStage = 0xF0; } } break; case 3: Argument16 = Argument8; case 4: if( received_byte == 0x0D ){ ParserStage += 0xCF; // -1 + 0xD0 }else if( received_byte == 0x0A ){ ParserStage += 0xDF; // -1 + 0xE0 }else{ ParserStage++; if ((received_byte >= 0x41) && (received_byte <= 0x46) ){ Argument16 = (Argument16 << 4) + (received_byte - 0x40 + 0x09); }else if( (received_byte >= 0x61) && (received_byte <= 0x66) ){ Argument16 = (Argument16 << 4) + (received_byte - 0x60 + 0x09); }else if( (received_byte >= 0x30) && (received_byte <= 0x39) ){ Argument16 = (Argument16 << 4) + (received_byte - 0x30); }else{ ParserStage = 0xF0; } } break; case 5: Argument32 = Argument16; case 6: case 7: case 8: if( received_byte == 0x0D ){ ParserStage += 0xCF; // -1 + 0xD0 }else if( received_byte == 0x0A ){ ParserStage += 0xDF; // -1 + 0xE0 }else{ ParserStage++; if ((received_byte >= 0x41) && (received_byte <= 0x46) ){ Argument32 = (Argument32 << 4) + (received_byte - 0x40 + 0x09); }else if( (received_byte >= 0x61) && (received_byte <= 0x66) ){ Argument32 = (Argument32 << 4) + (received_byte - 0x60 + 0x09); }else if( (received_byte >= 0x30) && (received_byte <= 0x39) ){ Argument32 = (Argument32 << 4) + (received_byte - 0x30); }else{ ParserStage = 0xF0; } } break; case 9: if( received_byte == 0x0D ){ ParserStage = 0xD8; }else if( received_byte == 0x0A ){ ParserStage = 0xE8; }else{ ParserStage = 0xF0; } break; case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: if( received_byte == 0x0A ){ ParserStage += 0x10; }else{ ParserStage = 0xF0; } break; case 0xF0: if( received_byte == 0x0A ){ ParserStage = 0xFF; } break; } switch( ParserStage ){ case 0xE0: if( Command == '?' ){ SendCharToUSB('@'); SendStringToUSB(DeviceName); Send_EOL_ToUSB(); }else if( Command == ':' ){ SendCharToUSB(':'); SendStringToUSB(BuildDate); Send_EOL_ToUSB(); }else if( (ErrNo = ExecuteCommand0(Command)) ){ SendCharToUSB('#'); SendCharToUSB(0x30+ErrNo); Send_EOL_ToUSB(); } ParserStage = 0; break; case 0xE1: case 0xE2: if( (ErrNo = ExecuteCommand2(Command,Argument8)) ){ SendCharToUSB('#'); SendCharToUSB(0x30+ErrNo); Send_EOL_ToUSB(); } ParserStage = 0; break; case 0xE3: case 0xE4: if( (ErrNo = ExecuteCommand4(Command,Argument16)) ){ SendCharToUSB('#'); SendCharToUSB(0x30+ErrNo); Send_EOL_ToUSB(); } ParserStage = 0; break; case 0xE5: case 0xE6: case 0xE7: case 0xE8: if( (ErrNo = ExecuteCommand8(Command,Argument32)) ){ SendCharToUSB('#'); SendCharToUSB(0x30+ErrNo); Send_EOL_ToUSB(); } ParserStage = 0; break; case 0xFF: SendCharToUSB('#'); Send_EOL_ToUSB(); ParserStage = 0; break; } }