00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <avr/io.h>
00024 #include <avr/signal.h>
00025 #include <avr/interrupt.h>
00026 #include <avr/pgmspace.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029
00030 #include "global.h"
00031 #include "cmdline.h"
00032
00033
00034 #include "cmdlineconf.h"
00035
00036
00037 #define ASCII_BEL 0x07
00038 #define ASCII_BS 0x08
00039 #define ASCII_CR 0x0D
00040 #define ASCII_LF 0x0A
00041 #define ASCII_ESC 0x1B
00042 #define ASCII_DEL 0x7F
00043
00044 #define VT100_ARROWUP 'A'
00045 #define VT100_ARROWDOWN 'B'
00046 #define VT100_ARROWRIGHT 'C'
00047 #define VT100_ARROWLEFT 'D'
00048
00049 #define CMDLINE_HISTORY_SAVE 0
00050 #define CMDLINE_HISTORY_PREV 1
00051 #define CMDLINE_HISTORY_NEXT 2
00052
00053
00054
00055
00056
00057 u08 PROGMEM CmdlinePrompt[] = "cmd>";
00058 u08 PROGMEM CmdlineNotice[] = "cmdline: ";
00059 u08 PROGMEM CmdlineCmdNotFound[] = "command not found";
00060
00061
00062
00063 static char CmdlineCommandList[CMDLINE_MAX_COMMANDS][CMDLINE_MAX_CMD_LENGTH];
00064
00065 static CmdlineFuncPtrType CmdlineFunctionList[CMDLINE_MAX_COMMANDS];
00066
00067 u08 CmdlineNumCommands;
00068
00069 u08 CmdlineBuffer[CMDLINE_BUFFERSIZE];
00070 u08 CmdlineBufferLength;
00071 u08 CmdlineBufferEditPos;
00072 u08 CmdlineInputVT100State;
00073 u08 CmdlineHistory[CMDLINE_HISTORYSIZE][CMDLINE_BUFFERSIZE];
00074 CmdlineFuncPtrType CmdlineExecFunction;
00075
00076
00077
00078
00079 static void (*cmdlineOutputFunc)(unsigned char c);
00080
00081 void cmdlineInit(void)
00082 {
00083
00084 CmdlineInputVT100State = 0;
00085
00086 CmdlineBufferLength = 0;
00087 CmdlineBufferEditPos = 0;
00088
00089 CmdlineExecFunction = 0;
00090
00091 CmdlineNumCommands = 0;
00092 }
00093
00094 void cmdlineAddCommand(u08* newCmdString, CmdlineFuncPtrType newCmdFuncPtr)
00095 {
00096
00097 strcpy(CmdlineCommandList[CmdlineNumCommands], newCmdString);
00098
00099 CmdlineFunctionList[CmdlineNumCommands] = newCmdFuncPtr;
00100
00101 CmdlineNumCommands++;
00102 }
00103
00104 void cmdlineSetOutputFunc(void (*output_func)(unsigned char c))
00105 {
00106
00107 cmdlineOutputFunc = output_func;
00108
00109
00110
00111
00112 }
00113
00114 void cmdlineInputFunc(unsigned char c)
00115 {
00116 u08 i;
00117
00118
00119
00120
00121 if(CmdlineInputVT100State == 2)
00122 {
00123
00124
00125 switch(c)
00126 {
00127 case VT100_ARROWUP:
00128 cmdlineDoHistory(CMDLINE_HISTORY_PREV);
00129 break;
00130 case VT100_ARROWDOWN:
00131 cmdlineDoHistory(CMDLINE_HISTORY_NEXT);
00132 break;
00133 case VT100_ARROWRIGHT:
00134
00135 if(CmdlineBufferEditPos < CmdlineBufferLength)
00136 {
00137
00138 CmdlineBufferEditPos++;
00139
00140 cmdlineOutputFunc(ASCII_ESC);
00141 cmdlineOutputFunc('[');
00142 cmdlineOutputFunc(VT100_ARROWRIGHT);
00143 }
00144 else
00145 {
00146
00147 cmdlineOutputFunc(ASCII_BEL);
00148 }
00149 break;
00150 case VT100_ARROWLEFT:
00151
00152 if(CmdlineBufferEditPos)
00153 {
00154
00155 CmdlineBufferEditPos--;
00156
00157 cmdlineOutputFunc(ASCII_BS);
00158 }
00159 else
00160 {
00161
00162 cmdlineOutputFunc(ASCII_BEL);
00163 }
00164 break;
00165 default:
00166 break;
00167 }
00168
00169 CmdlineInputVT100State = 0;
00170 return;
00171 }
00172 else if(CmdlineInputVT100State == 1)
00173 {
00174
00175 if(c == '[')
00176 {
00177 CmdlineInputVT100State = 2;
00178 return;
00179 }
00180 else
00181 CmdlineInputVT100State = 0;
00182 }
00183 else
00184 {
00185
00186 CmdlineInputVT100State = 0;
00187 }
00188
00189
00190 if( (c >= 0x20) && (c < 0x7F) )
00191 {
00192
00193
00194 if(CmdlineBufferEditPos == CmdlineBufferLength)
00195 {
00196
00197 cmdlineOutputFunc(c);
00198
00199 CmdlineBuffer[CmdlineBufferEditPos++] = c;
00200
00201 CmdlineBufferLength++;
00202 }
00203 else
00204 {
00205
00206
00207
00208 CmdlineBufferLength++;
00209 for(i=CmdlineBufferLength; i>CmdlineBufferEditPos; i--)
00210 CmdlineBuffer[i] = CmdlineBuffer[i-1];
00211
00212 CmdlineBuffer[CmdlineBufferEditPos++] = c;
00213
00214 cmdlineRepaint();
00215
00216 for(i=CmdlineBufferEditPos; i<CmdlineBufferLength; i++)
00217 cmdlineOutputFunc(ASCII_BS);
00218 }
00219 }
00220
00221 else if(c == ASCII_CR)
00222 {
00223
00224
00225 cmdlineOutputFunc(ASCII_CR);
00226 cmdlineOutputFunc(ASCII_LF);
00227
00228 CmdlineBuffer[CmdlineBufferLength++] = 0;
00229 CmdlineBufferEditPos++;
00230
00231 cmdlineProcessInputString();
00232
00233 CmdlineBufferLength = 0;
00234 CmdlineBufferEditPos = 0;
00235 }
00236 else if(c == ASCII_BS)
00237 {
00238 if(CmdlineBufferEditPos)
00239 {
00240
00241 if(CmdlineBufferEditPos == CmdlineBufferLength)
00242 {
00243
00244
00245 cmdlineOutputFunc(ASCII_BS);
00246 cmdlineOutputFunc(' ');
00247 cmdlineOutputFunc(ASCII_BS);
00248
00249 CmdlineBufferLength--;
00250 CmdlineBufferEditPos--;
00251 }
00252 else
00253 {
00254
00255
00256
00257 CmdlineBufferLength--;
00258 CmdlineBufferEditPos--;
00259 for(i=CmdlineBufferEditPos; i<CmdlineBufferLength; i++)
00260 CmdlineBuffer[i] = CmdlineBuffer[i+1];
00261
00262 cmdlineRepaint();
00263
00264 cmdlineOutputFunc(' ');
00265
00266 for(i=CmdlineBufferEditPos; i<(CmdlineBufferLength+1); i++)
00267 cmdlineOutputFunc(ASCII_BS);
00268 }
00269 }
00270 else
00271 {
00272
00273 cmdlineOutputFunc(ASCII_BEL);
00274 }
00275 }
00276 else if(c == ASCII_DEL)
00277 {
00278
00279 }
00280 else if(c == ASCII_ESC)
00281 {
00282 CmdlineInputVT100State = 1;
00283 }
00284 }
00285
00286 void cmdlineRepaint(void)
00287 {
00288 u08* ptr;
00289 u08 i;
00290
00291
00292 cmdlineOutputFunc(ASCII_CR);
00293
00294 cmdlinePrintPrompt();
00295
00296 i = CmdlineBufferLength;
00297 ptr = CmdlineBuffer;
00298 while(i--) cmdlineOutputFunc(*ptr++);
00299 }
00300
00301 void cmdlineDoHistory(u08 action)
00302 {
00303 switch(action)
00304 {
00305 case CMDLINE_HISTORY_SAVE:
00306
00307 if( strlen(CmdlineBuffer) )
00308 strcpy(CmdlineHistory[0], CmdlineBuffer);
00309 break;
00310 case CMDLINE_HISTORY_PREV:
00311
00312 strcpy(CmdlineBuffer, CmdlineHistory[0]);
00313
00314 CmdlineBufferLength = strlen(CmdlineBuffer);
00315 CmdlineBufferEditPos = CmdlineBufferLength;
00316
00317 cmdlineRepaint();
00318 break;
00319 case CMDLINE_HISTORY_NEXT:
00320 break;
00321 }
00322 }
00323
00324 void cmdlineProcessInputString(void)
00325 {
00326 u08 cmdIndex;
00327 u08 i=0;
00328
00329
00330 cmdlineDoHistory(CMDLINE_HISTORY_SAVE);
00331
00332
00333
00334 while( !((CmdlineBuffer[i] == ' ') || (CmdlineBuffer[i] == 0)) ) i++;
00335
00336 if(!i)
00337 {
00338
00339
00340 cmdlinePrintPrompt();
00341
00342 return;
00343 }
00344
00345
00346 for(cmdIndex=0; cmdIndex<CmdlineNumCommands; cmdIndex++)
00347 {
00348 if( !strncmp(CmdlineCommandList[cmdIndex], CmdlineBuffer, i) )
00349 {
00350
00351
00352 CmdlineExecFunction = CmdlineFunctionList[cmdIndex];
00353
00354
00355 return;
00356 }
00357 }
00358
00359
00360
00361 cmdlinePrintError();
00362
00363 cmdlinePrintPrompt();
00364 }
00365
00366 void cmdlineMainLoop(void)
00367 {
00368
00369 if(CmdlineExecFunction)
00370 {
00371
00372 CmdlineExecFunction();
00373
00374 CmdlineExecFunction = 0;
00375
00376 cmdlinePrintPrompt();
00377 }
00378 }
00379
00380 void cmdlinePrintPrompt(void)
00381 {
00382
00383 u08* ptr = CmdlinePrompt;
00384 while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
00385 }
00386
00387 void cmdlinePrintError(void)
00388 {
00389 u08 * ptr;
00390
00391
00392
00393 ptr = (u08*)CmdlineNotice;
00394 while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
00395
00396
00397 ptr = CmdlineBuffer;
00398 while((*ptr) && (*ptr != ' ')) cmdlineOutputFunc(*ptr++);
00399
00400 cmdlineOutputFunc(':');
00401 cmdlineOutputFunc(' ');
00402
00403
00404
00405 ptr = (u08*)CmdlineCmdNotFound;
00406 while(pgm_read_byte(ptr)) cmdlineOutputFunc( pgm_read_byte(ptr++) );
00407
00408 cmdlineOutputFunc('\r');
00409 cmdlineOutputFunc('\n');
00410 }
00411
00412
00413
00414
00415 u08* cmdlineGetArgStr(u08 argnum)
00416 {
00417
00418 u08 idx=0;
00419 u08 arg;
00420
00421
00422 while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] == ' ')) idx++;
00423
00424
00425 for(arg=0; arg<argnum; arg++)
00426 {
00427
00428 while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] != ' ')) idx++;
00429
00430 while( (CmdlineBuffer[idx] != 0) && (CmdlineBuffer[idx] == ' ')) idx++;
00431 }
00432
00433 return &CmdlineBuffer[idx];
00434 }
00435
00436
00437 long cmdlineGetArgInt(u08 argnum)
00438 {
00439 char* endptr;
00440 return strtol(cmdlineGetArgStr(argnum), &endptr, 10);
00441 }
00442
00443
00444 long cmdlineGetArgHex(u08 argnum)
00445 {
00446 char* endptr;
00447 return strtol(cmdlineGetArgStr(argnum), &endptr, 16);
00448 }