|
|
View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
Implementing a command line interface |
Posted: Sun Sep 10, 2006 7:28 am |
|
|
Hi,
I am looking for algorithms to implement a simple command line interface, like the ones from DOS and Matlab.
The two ways I can think are a state machine and comparing full commands against a "database".
Which way do you think I should try?
Thank you. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Sep 10, 2006 11:37 am |
|
|
Here is an example of what I do. It was written for the C18 compiler so you will have to work around the pointer to rom.
Code: |
/*$F********************************************************************
*
* Copyright (C)pa 1997-2004 Lithonia Lighting
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Functional
* Description: This module is designed to provide diagnostic terminal
* support
*
* $Log: /Synergy/Input Card/Source/terminal.c $
*
* 2 8/05/04 4:58p Mark
*
* 1 7/30/04 4:17p Mark
*
*********************************************************************/
/* compiler includes */
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <i2c.h>
/* our includes */
#include "stdint.h"
#include "mystring.h"
#include "comm.h"
#include "terminal.h"
#include "eeprom.h"
#include "stptok.h"
#include "bi.h"
#include "ai.h"
#include "version.h"
#include "sprintf.h"
#include "util.h"
#include "stptok.h"
#include "sscanf.h"
#include "selftest.h"
#include "hardware.h"
#include "abus.h"
/* local typedefs */
typedef rom struct _cmd_t
{
const rom char *pStr; /* command */
void (*pFunction) (char *pCmd, char *pArgs); /* command function */
const rom char *pDescription; /* command description (for help) */
} COMMAND_DATA;
/* function prototypes */
static void PrintStatus(char status);
static void SelfTestCommand(char *pCmd, char *pArgs);
static void VirginCommand(char *pCmd, char *pArgs);
static void BootCommand(char *pCmd, char *pArgs);
void VersionCommand(char *pCmd, char *pArgs);
static void ABUSCommand(char *pCmd, char *pArgs);
static void InputCommand(char *pCmd, char *pArgs);
static void StatusCommand(char *pCmd, char *pArgs);
static void EEPROMDumpCommand(char *pCmd, char *pArgs);
static void HostModeCommand(char *pCmd, char *pArgs);
static void ReInitCommand(char *pCmd, char *pArgs);
static void RestartCommand(char *pCmd, char *pArgs);
static void THelpCommand(char *pCmd, char *pArgs);
static void VHelpCommand(char *pCmd, char *pArgs);
static bool CommandHandler(char *pArgs, COMMAND_DATA *pCommandData);
static void VerboseHelpHandler(COMMAND_DATA *pCommandData);
static void TerseHelpHandler(char *pArgs, COMMAND_DATA *pCommandData);
void TerminalHandler();
#pragma idata Terminal_Table
static COMMAND_DATA CommandData[] =
{
/* hidden commands - description is NULL */
{ { "help" }, VHelpCommand, { NULL } },
{ { "TEST" }, SelfTestCommand, { NULL } },
{ { "VIRGINIZE" }, VirginCommand, { NULL } },
{ { "bootmode" }, BootCommand, { NULL } },
{ { "dump" }, EEPROMDumpCommand,{ NULL } },
/* application commands */
{ { "abus" }, ABUSCommand, { "sends command out abus" } },
{ { "host" }, HostModeCommand, { "allows this device to act as host" } },
{ { "input" }, InputCommand, { "input control" } },
{ { "restart" }, RestartCommand, { "restart device" } },
{ { "restore" }, ReInitCommand, { "restore defaults" } },
{ { "status" }, StatusCommand, { "input status" } },
{ { "ver" }, VersionCommand, { "sofware version" } },
{ { "??" }, VHelpCommand, { "verbose help" } },
{ { "?" }, THelpCommand, { "terse help" } },
{ { NULL }, NULL, { NULL } },
};
#pragma idata vars
/* *************************************************************************
DESCRIPTION: Prints status of ok or fail. PARAMETERS: port (IN) port to
print to status (IN) TRUE if OK, FALSE if fail GLOBALS:
none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void PrintStatus(
char status) /* FIX ME: add comment */
{
if (status)
Comm_PutRomString("Ok\r\n");
else
Comm_PutRomString("Fail\r\n");
return;
}
/* *************************************************************************
DESCRIPTION: List the IO Mapping for an input
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
void EEPROMDumpCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
char buf[MAX_LINE_LEN]; /* local buffer */
uint16_t n = 0; // index to counter
uint16_t num;
uint16_t row = 0;
(void)pCmd;
(void)pArgs;
Comm_PutRomString(" ");
for (num = 0; num < 16; num++)
{
sprintf(buf, "%02x ", num);
Comm_PutString(buf);
}
// for (n = 0; n <= SEEPROM_SIZE; n++)
for (n = 0; n <= 64; n++)
{
if (!(n & 0x0F))
{
sprintf(buf, "\r\n%02x ", row);
Comm_PutString(buf);
row++;
}
num = EEPROM_Read(n);
sprintf(buf, "%02x ", num);
Comm_PutString(buf);
}
Comm_PutRomString("\r\n");
}
/* *************************************************************************
DESCRIPTION: Allows this card to act as ABUS host
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
void HostModeCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
(void)pCmd;
if (strncmpipgm2ram(pArgs, "true", 4) == 0)
{
ABUS_HostMode(TRUE);
PrintStatus(TRUE);
}
else if (strncmpipgm2ram(pArgs, "false", 5) == 0)
{
ABUS_HostMode(FALSE);
PrintStatus(TRUE);
}
else
{
Comm_PutRomString("Examples:\r\n");
Comm_PutString(pCmd);
Comm_PutRomString(" TRUE - starts host mode\r\n");
Comm_PutString(pCmd);
Comm_PutRomString(" FALSE - exits host mode\r\n");
}
return;
}
/* *************************************************************************
DESCRIPTION: Sends command out the ABUS
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void ABUSCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
#define BUFFER_SIZE 40
uint8_t buf[40];
char temp[5];
uint8_t i = 0;
(void)pCmd;
buf[0] = TX_READY;
while (pArgs)
{
i++;
if (i >= BUFFER_SIZE)
{
PrintStatus(FALSE);
return;
}
pArgs = stptok(pArgs, temp, sizeof(temp), " ");
if (strlen(temp) > 3)
{
PrintStatus(FALSE);
return;
}
buf[i] = atob(temp);
}
if ( buf[1] == ABUS_Fixed_Address )
{
buf[0] = PROCESS_OK;
ABUS_Process_Message((union RX_MSG*)buf, sizeof(buf));
}
else
{
if (ABUS_Transmit(buf, sizeof(buf)))
PrintStatus(TRUE);
else
PrintStatus(FALSE);
}
return;
}
/* *************************************************************************
DESCRIPTION: Restarts the event scheduler GLOBALS: none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void RestartCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
(void)pCmd;
(void)pArgs;
{
_asm clrwdt reset _endasm
}
}
/* *************************************************************************
DESCRIPTION: Re-initializes all the modules data GLOBALS: none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void ReInitCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
(void)pCmd;
(void)pArgs;
/* Reinit */
Hardware_Initialize_Device();
PrintStatus(TRUE);
return;
}
/* *************************************************************************
DESCRIPTION: Programs the switch data
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void InputCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
char buf[MAX_LINE_LEN]; /* local buffer */
uint8_t address;
uint8_t count;
// expecting: "INPUT 1 ON " "INPUT 1 OFF"
if (pArgs)
{
count = sscanf(pArgs, "%b %s", &address, buf);
// Our address is one less than the user address
address--;
if (address >= HARDWARE_MAX_BINARY_INPUTS)
{
PrintStatus(FALSE);
return;
}
if (count == 2)
{
if (strcmpipgm2ram(buf, "ON") == 0)
{
BI_Event(address, ON);
PrintStatus(TRUE);
}
else if (strcmpipgm2ram(buf, "OFF") == 0)
{
BI_Event(address, OFF);
PrintStatus(TRUE);
}
else
{
PrintStatus(FALSE);
}
}
}
// User must need help
else
{
Comm_PutRomString("Examples:\r\n");
Comm_PutString(pCmd);
Comm_PutRomString(" 1 ON\r\n");
Comm_PutString(pCmd);
Comm_PutRomString(" 1 OFF\r\n");
}
return;
}
/* *************************************************************************
DESCRIPTION: Prints the input status
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void StatusCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
char buf[MAX_LINE_LEN]; /* local buffer */
uint8_t input = 0;
(void)pCmd;
(void)pArgs;
while (input < HARDWARE_MAX_BINARY_INPUTS)
{
sprintf(buf, "INPUT %-2b ", (char)(input + 1));
Comm_PutString(buf);
if ( BI_Get_Level(input) )
Comm_PutRomString("(1) ACTIVE");
else
Comm_PutRomString("(0) INACTIVE");
Comm_PutRomString("\r\n");
input++;
}
input = 0;
while (input < HARDWARE_MAX_ANALOG_INPUTS)
{
sprintf(buf, "PHOTOCELL %-2b %b\r\n", (char)(input + 1), (char)AI_Get_Level(input));
Comm_PutString(buf);
input++;
}
return;
}
/* *************************************************************************
DESCRIPTION: Displays the version of the code.
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
void VersionCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
char buf[MAX_LINE_LEN]; /* local buffer */
(void)pCmd;
(void)pArgs;
sprintf(buf, "Module: %S\r\nVersion: %S\r\n", PROGRAM_NAME, CODE_VERSION);
Comm_PutString(buf);
sprintf(buf, "Built: %S\r\nAddress: %b\r\n", BUILD_DATE, Hardware_Get_Fixed_Address());
Comm_PutString(buf);
return;
}
/* *************************************************************************
DESCRIPTION: Puts the device into the bootloader
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void BootCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
/* To enter bootmode, write 'b' to the last location in the �
* internal eeprom */
if (pArgs)
{
/* This is an attempt to try and make it difficult to enter
* boot mode with run away code */
if (*pArgs == 'b')
{
EEPROM_Write_Internal(0xFF, *pArgs);
/* restart the application */
{
_asm reset _endasm
}
}
}
PrintStatus(FALSE);
}
/* *************************************************************************
DESCRIPTION: Executes the self test mode
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void SelfTestCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
Selftest_Execute();
}
/* *************************************************************************
DESCRIPTION: Sets the EEPROMS to the "virgin" state
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void VirginCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
uint16_t i;
for (i = 0; i <= EEPROM_LAST_ADDRESS; i++)
{
EEPROM_Write(i, 0xFF);
ClrWdt();
}
for (i = 0; i < 0xFF; i++)
{
EEPROM_Write_Internal(i, 0xFF);
ClrWdt();
}
/* Write a 0 to the last location of the EEPROM to prevent going into �
* bootmode */
EEPROM_Write_Internal(i, 0x00);
PrintStatus(TRUE);
/* wait for a wdt timeout */
while (1);
}
/* *************************************************************************
This section consists of generic routines handling the commands from a
data table
*************************************************************************** */
/* *************************************************************************
DESCRIPTION: Handles the terminal operation PARAMETERS: port (IN)
communication port pCmd (IN) command arguments GLOBALS:
none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static bool CommandHandler(
char *pArgs, /* FIX ME: add comment */
COMMAND_DATA *pCommandData) /* FIX ME: add comment */
{
static char cmd[MAX_LINE_LEN]; /* local buffer */
bool found = 0; /* valid command? */
if (pArgs)
{
/* parse and remove the only the first command */
pArgs = stptok(pArgs, cmd, sizeof(cmd), " ");
/* find and execute command function */
while (pCommandData->pStr != NULL)
{
if (strcmpipgm2ram(cmd, pCommandData->pStr) == 0)
{
if (pCommandData->pFunction != NULL)
{
(void)strupr(cmd);
(void)pCommandData->pFunction(cmd, pArgs);
}
found = 1;
break;
}
pCommandData++;
}
}
return (found);
}
/* *************************************************************************
DESCRIPTION: Displays the help information strings PARAMETERS: port (IN)
communication port pCommandData (IN) data table GLOBALS:
none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void VerboseHelpHandler(
COMMAND_DATA *pCommandData) /* FIX ME: add comment */
{
char buf[MAX_LINE_LEN]; /* string to print */
/* spew the commands and their help */
while (pCommandData->pStr != NULL)
{
if (pCommandData->pDescription != NULL)
{
sprintf(buf, "%-10S - %S\r\n", pCommandData->pStr, pCommandData->pDescription);
Comm_PutString(buf);
}
pCommandData++;
}
Comm_PutRomString("\r\n");
return;
}
/* *************************************************************************
DESCRIPTION: Handles the display of help - verbose PARAMETERS: port (IN)
communication port pCmd (IN) command arguments pCommandData
(IN) data table GLOBALS: none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void TerseHelpHandler(
char *pArgs, /* FIX ME: add comment */
COMMAND_DATA *pCommandData) /* FIX ME: add comment */
{
char buf[MAX_LINE_LEN]; /* string to print */
uint8_t count = 0; /* to put 4 words on a line */
/* if the user wanted help about a specific item, show that item */
if (pArgs)
{
while (pCommandData->pStr != NULL)
{
if (strcmpram2pgm(pCommandData->pStr, pArgs) == 0)
{
if (pCommandData->pDescription != NULL)
{
sprintf(buf, "%-10S - %S\r\n", pCommandData->pStr, pCommandData->pDescription);
Comm_PutString(buf);
}
break;
}
++pCommandData;
}
}
/* print them all */
else
{
count = 0;
while (pCommandData->pStr != NULL)
{
if (pCommandData->pDescription != NULL)
{
sprintf(buf, "%-8S", pCommandData->pStr);
Comm_PutString(buf);
count++;
if (count >= 4)
{
Comm_PutRomString("\r\n");
count = 0;
}
else
Comm_PutRomString("\t");
}
++pCommandData;
}
Comm_PutRomString("\r\n");
}
return;
}
/* *************************************************************************
DESCRIPTION: Displays the help information strings PARAMETERS: port (IN)
communication port pCmd (IN) optional arguments GLOBALS:
none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void THelpCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
(void)pCmd;
/* spew the program data in a terse manner */
TerseHelpHandler(pArgs, &CommandData[0]);
return;
}
/* *************************************************************************
DESCRIPTION: Displays the help information strings PARAMETERS: port (IN)
communication port pCmd (IN) optional arguments GLOBALS:
none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
static void VHelpCommand(
char *pCmd, /* (IN) command string */
char *pArgs) /* (IN) optional arguments */
{
(void)pArgs;
(void)pCmd;
/* spew the program data */
VerboseHelpHandler(&CommandData[0]);
return;
}
/* *************************************************************************
DESCRIPTION: Handles the terminal operation PARAMETERS: port (IN)
communication port GLOBALS: none
RETURN: none
ALGORITHM: none
NOTES: none
*************************************************************************** */
void TerminalHandler()
{
static uint8_t index = 0; /* index of buffer */
char ch; /* character from buffer */
static char buf[MAX_LINE_LEN]; /* for the line entry */
while (TRUE)
{
if ( !Comm_IsBufferReady() )
return;
ch = Comm_GetChar();
switch (ch)
{
/* illegal characters */
case '\a':
case '\f':
case '\n':
case '\t':
case '\v':
/* escape */
case 0x1B:
break;
/* backspace */
case '\b':
if (index)
{
--index;
/* do a destructive backspace */
Comm_PutChar('\b');
Comm_PutChar(' ');
Comm_PutChar('\b');
}
break;
/* enter */
case '\r':
Comm_PutChar('\r');
Comm_PutChar('\n');
buf[index] = '\0';
/* did we get something? */
if (index)
{
if (!CommandHandler(buf, &CommandData[0]))
Comm_PutRomString("Invalid Command. Type ? for help.\r\n");
}
buf[0] = '\0';
index = 0;
/* write the prompt */
Comm_PutChar('>');
break;
/* all the rest of the characters */
default:
/* leave room for null at the end */
if (index < (MAX_LINE_LEN - 1))
{
buf[index] = ch;
if (!ch)
ch = 0;
Comm_PutChar(ch);
index++;
}
break;
}
}
}
|
and
Code: |
/*$F********************************************************************
*
* stptok() -- public domain by Ray Gardner, modified by Bob Stout,
* Steve Karg, and Mark Norton
*
* Functional
* Description: This file contains the stptok function
*
* $Log: /Synergy/Input Card/Source/stptok.c $
*
* 1 7/30/04 4:17p Mark
*
* 6 10/08/03 5:02p Mark
*
* 5 10/07/03 4:48p Mark
*
*
*********************************************************************/
#include <stddef.h>
/* *************************************************************************
DESCRIPTION: You pass this function a string to parse, a buffer to
receive the "token" that gets scanned, the length of the
buffer, and a string of "break" characters that stop the
scan. It will copy the string into the buffer up to any of
the break characters, or until the buffer is full, and will
always leave the buffer null-terminated. It will return a
pointer to the first non-breaking character after the one
that stopped the scan.
RETURN: It will return a pointer to the first non-breaking character
after the one that stopped the scan or NULL on error or end of
string.
ALGORITHM: none
*************************************************************************** */
char *stptok(
const char *s, /* string to parse */
char *tok, /* buffer that receives the "token" that gets scanned */
size_t toklen, /* length of the buffer */
const rom char *brk) /* string of break characters that will stop the scan */
{
char *lim; /* limit of token */
const rom char *b; /* current break character */
/* check for invalid pointers */
if (!s || !tok || !brk)
return (NULL);
/* check for empty string */
if (!*s)
return (NULL);
lim = tok + toklen - 1;
while (*s && tok < lim)
{
for (b = brk; *b; b++)
{
if ((*s == *b) || (*s == '\r') || (*s == '\n'))
{
*tok = 0;
for (++s, b = brk; *s && *b; ++b)
{
if (*s == *b)
{
++s;
b = brk;
}
}
if (!*s)
return (NULL);
return (char *)s;
}
}
*tok++ = *s++;
}
*tok = 0;
if (!*s)
return (NULL);
return (char *)s;
}
|
Last edited by Mark on Mon Sep 11, 2006 4:52 am; edited 2 times in total |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Sep 10, 2006 2:46 pm |
|
|
Thank you for the code, it will be a good learning tool.
I think that the CommandHandler() function, maybe the one that calls stptok(), is not included. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Sep 10, 2006 9:04 pm |
|
|
future wrote: | Thank you for the code, it will be a good learning tool.
I think that the CommandHandler() function, maybe the one that calls stptok(), is not included. |
Had to disable HTML in the post |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Mon Sep 11, 2006 4:47 am |
|
|
I saw that you edited the post, did you add something?
I still can't see the function.. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Sep 11, 2006 4:53 am |
|
|
future wrote: | I saw that you edited the post, did you add something?
I still can't see the function.. | Try it now |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sat Sep 16, 2006 5:14 pm |
|
|
Thank you very much! |
|
|
Guest
|
Convert to CCC |
Posted: Wed Apr 11, 2007 3:59 am |
|
|
Hi,
Is there anybody convert to CCS C this code?
Thanks.
CENAtronics |
|
|
srhoar
Joined: 17 Apr 2007 Posts: 3
|
|
Posted: Sat May 05, 2007 9:10 am |
|
|
Here is the state machine and parser I use for most of my projects.
It is fairly simple to modify.
Code: |
#include <string.h>
#include <stdlib.h>
typedef enum { FAULT = 0, STBY, ARMED, FIRE } State_Type;
const char state_text[4][6] = { "FAULT", "STBY", "ARMED", "FIRE" };
void state_table(void);
State_Type curr_state = FAULT;
char line[17]; /* variables for parser */
int i, c;
/* LIST ALL COMMAND TO RECOGNIZE HERE */
#define NUM_COMMANDS 10
#define EOL '\r'
const char commands[NUM_COMMANDS + 1][10] = {
"FIRE", "STBY", "STAT", "SHOTS",
"ARM", "PRF", "RED", "TEST",
"HELP","NOHV" };
/* function protoypes void */
void safe_system(void);
void state_stby(void);
void state_armed(void);
void state_fire(void);
void state_fault(void);
void debug_test(void);
void get_command(void);
void send_stat(void);
void delay_s(int);
void help(void);
int delay = 0; /* used for state delays */
/*
=======================================================================================================================
=======================================================================================================================
*/
void main()
{
/* CHIP SETUPS */
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED, 0, 1);
output_high(PIN_B6); /* prevent slave resets */
port_b_pullups(TRUE);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
safe_system();
while(1)
{
/* wait for command */
get_command();
printf("STATE=%d\n\r", curr_state);
state_table();
delay_ms(delay);
delay = 0;
}
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void state_table()
{
switch(curr_state)
{
case FAULT: state_fault(); break;
case STBY: state_stby(); break;
case ARMED: state_armed(); break;
case FIRE: state_fire(); break;
}
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void safe_system(void)
{
printf("SAFE ");
help();
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void state_stby()
{
printf("STBY ");
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void state_armed()
{
printf("ARMED ");
return;
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void state_fire()
{
curr_state = ARMED;
return;
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void state_fault()
{
printf("FAULT ");
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void debug_test()
{
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void get_command()
{
/*~~~~~~~~~~~~~~~~~~~*/
/* NEW PARSER */
char index, j;
char found = 0;
char command = 0;
char lookup_str[12];
char name[17];
char val[17];
/*~~~~~~~~~~~~~~~~~~~*/
/*
* printf("Parser\r\n");
*/
while(1)
{
state_table();
printf(">");
for(i = 0; i < 17; i++) line[i] = 0; /* clear the line buffer */
for(i = 0; i <= 16; i++)
{ /* get a whole line but limit it to buffer size */
if((c = getch()) == EOL) break;
line[i] = c; /* add the character to the line buffer */
} /* end for loop */
if(i < 3) continue; /* may be a blank line, just skip it, variables must be more than 3 */
line[i] = '\0';
for(i = 0; (line[i] != ' ') && (i < 10) && (line[i] != '\0'); i++)
{
name[i] = line[i]; /* extract the first word up to a space character */
}
name[i] = '\0'; /* terminate the string! */
if(line[i] != '\0')
{
i++; /* skip the space character */
j = 0;
for(; (i < 10) && (line[i] != '\0'); i++)
{
val[j++] = line[i]; /* now extract the rest of the line, the "value" */
}
val[j] = '\0';
}
/* LOOK UP COMMAND */
found = 0; /* set to not found to start */
command = 0;
for(index = 0; index < NUM_COMMANDS; index++)
{
sprintf(lookup_str, "%s", commands[index]);
if(strcmp(name, lookup_str) == 0)
{
found = 1; /* COMMAND IS IN TABLE */
command = index;
}
}
if(found == 1) /* COMMAND IS VALID */
{
printf("OK\r\n");
switch(command)
{
case 0: /* FIRE */if(curr_state == ARMED) curr_state = FIRE; break;
case 1: /* STBY */curr_state = STBY; break;
case 2: /* STAT */send_stat(); break;
case 3: /* SHOTS X */shots = atol(val); break;
case 4: /* ARM */if(curr_state == STBY) curr_state = ARMED; break;
case 5: /* PRF */prf = atol(val); break;
case 6: /* RED */red(); break;
case 7: /* TEST */debug_test(); break;
case 8: /* HELP */help(); break;
case 9: /* NOHV */nohv=1; break;
default: break;
}
}
else
printf("ERROR\r\n"); /* COMMAND NOT FOUND */
state_table();
}
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void send_stat()
{
printf("\n\rSTAT\n\r");
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void help()
{
printf("\nBlackjack controller V1.0\n\r");
printf("Commands:\n\r");
printf("STAT - Status of system\n\r");
printf("STBY - Put system in Standby\n\r");
printf("ARM - Arm the system and turn on the SSU\n\r");
printf("FIRE - Fire the system\n\r");
printf("SHOTS # - Set the number of shots to Fire\n\r");
printf("PRF # - Set the PRF of the System\n\r");
printf("\n\r");
printf("Written by Robert 'Red' Hoar for LMMFC - Dallas\n\r");
printf("\n\r");
}
|
_________________ ===================
|Robert 'Red' Hoar
|
|Program Manager
|Directed Energy RF
=================== |
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
Mark, can you help ? |
Posted: Sat May 05, 2007 10:07 am |
|
|
I do wish Mark would convert his code to CCS from microchip C.
I think his approach is very good, and would make the basis of a very flexible command line parser.
Unfortunately, I dont have the C skill to do it.
please Mark if V4.033 is now functional for pointer to rom etc, could you have a go
Mike |
|
|
Steve H. Guest
|
|
Posted: Tue May 08, 2007 3:05 pm |
|
|
Future - While the parser presented is very, very good you might find a simpler one suitable for your needs. I designed a very simple one several years back. You can download it from the ARRL.org website at,
arrl.org/files/
search for PIC_DAS
It was written for PCM version 2.6XX but I think it should run under 4.XXX.
At any rate - it is a simpler - albeit not as functionally nice alternative, but it does work.
HTH - Steve H. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|