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