⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.c

📁 PEAKAUDIO用于EV2板的MCU控制源码
💻 C
字号:
/*************************************************************************

	command.c

  This is the CobraNet Module line command processing module.

	Besides parsing the line command, this module also provides support
	functions and routines for validating the line command parameters.

	Copyright (C) 2001-2004 by Cirrus Logic Inc. All Rights Reserved
*************************************************************************/

#include <8051.h>
#include <intrpt.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include "serial.h"
#include "command.h"
#include "test.h"
#include "hmi.h"
#include "error.h"
#include "mib.h"
#include "led.h"
#include "query.h"
#include "cnmutil.h"
#include "audio.h"
#include "packet.h"
#include "evif.h"
#include "mystrings.h"
#include "host_reg.h"

#define cESC_KEY_IGNORE		0
#define cESC_KEY_RIGHT		1
#define cESC_KEY_LEFT			2
#define cESC_KEY_CANCEL		3
#define cESC_KEY_NOT			4
#define cESC_KEY_FUNCTION	5

static char *command_arg_ptr[ cNUM_COM_ARG ];
static char command_buffer[ cCMND_BUF_SIZE ];

void parse_line_command( char * line_command_ptr, char *com_arg_ptr[] );
void process_line_command( char * com_arg_ptr[] );
unsigned char command_in_list( char * line_command_ptr );
unsigned char do_escape( char * ret_char );

extern near unsigned char gRXD_RD_idx;
extern near unsigned char gRXD_WR_idx;

//this is the array of line command function pointers.
code struct command_item_t * code command_list[] =	{
	&peek_command,
	&poke_command,
	&route_command,
	&led_command,
	&query_command,
	&audio_command,
	&testev_command,
	&packet_command,
	&read_command,
	&write_command,
	&peekev_command,
	&pokeev_command,
	NULL
};

extern void service_Line_Command( void )	{
	//this keeps sucking in characters until a carriage return or linefeed
	unsigned char c = 0;
	static unsigned short counter = 0;	//ignore backspace as first chars,
																			//until counter != 0
	static char * edit_ptr = command_buffer;
	unsigned char escape_char = 0;
	unsigned char init_buffer = 0;

	if ( edit_ptr == command_buffer )	{
		*edit_ptr = cASCII_NULL;
		*( edit_ptr + 1 ) = cASCII_NULL;
	}
	c = getch();
	if ( ( c != cASCII_CR ) && ( c != cASCII_LF ) )	{
		switch( c )	{
			case cASCII_BS:								//deal with backspaces
				putch( c );
				putch( ' ' );
				putch( c );
				if ( counter != 0 )	{
					*--edit_ptr = cASCII_NULL;
					counter--;
				}
				else
					printStrCode( str_Prompt );
				break;
			case cASCII_CNTRLC:						//a control-c aborts the input
				printStrCodeC( str_Prompt );
				init_buffer = 1;
				break;
			case cASCII_ESC:							//for the future, escape control?
				escape_char = do_escape( ( char * ) &c );
				switch( escape_char )	{
					case cESC_KEY_IGNORE:
					case cESC_KEY_NOT:
					case cESC_KEY_FUNCTION:	//ignore for now, maybe something later.
					case cESC_KEY_RIGHT:		//ditto
					case cESC_KEY_LEFT:			//ditto
							waiting( 0x0606,0x00 );	//about 2.2ms
							if ( gRXD_RD_idx != gRXD_WR_idx )
								c = getch();					//clear out buffer
						break;
					case cESC_KEY_CANCEL:
						printStrCode( str_CRLF );					//send a CR/LF
						printStrCode( str_Prompt );
						init_buffer = 1;
						break;
					default:
						break;
				};
				break;
			default:
				putch( c );
				if ( isupper( c ) )
						c += 'a' - 'A';
				*edit_ptr++ = c;
				if ( *edit_ptr == cASCII_NULL )
					*( edit_ptr + 1 ) = cASCII_NULL;
				counter++;
				break;
		};	//switch
	}
	else	{
		putch( c );
		//*edit_ptr = cASCII_NULL;		//null terminate string

		printStrCode( str_CRLF );					//send a CR/LF

		parse_line_command( command_buffer, command_arg_ptr );

		process_line_command( command_arg_ptr );
		putch( '>' );
		init_buffer = 1;
	}
	if ( init_buffer ) {
		edit_ptr = command_buffer;
		counter = 0;
		init_buffer = 0;
	}
}

unsigned char do_escape( char * ret_char )	{
//this is mostly for possible expansion, not used at this time.
	unsigned char c;
	unsigned short cntr = 0;
	unsigned char esc_code = cESC_KEY_IGNORE;
	
	do
		cntr++;
	while ( ( gRXD_RD_idx == gRXD_WR_idx ) &&  ( cntr != 350 ) );	// ~1 ms
//if another character is waiting than not just escape
	if ( gRXD_RD_idx != gRXD_WR_idx )	{		
		c = getch();	//get next character
		if ( c == cASCII_LB )	{	//this is part of the control sequence '['
			c = getch();	//get the main control char
			switch ( c )	{//only support a limited set of control char
				case 'C':		//right arrow
					esc_code = cESC_KEY_RIGHT;
					break;
				case 'D':		//left arrow
					esc_code = cESC_KEY_LEFT;
					break;
				default:
					esc_code = cESC_KEY_IGNORE;
					break;
			};
		}
		else {//if not part of the control sequence
			if ( c == 'O' )	{	//this detects a function key press
				*ret_char = getch();		//return which key
				esc_code = cESC_KEY_FUNCTION;
			}
			else	{
				*ret_char = c;		//need this to process it if valid?????
				esc_code = cESC_KEY_NOT;
			}
		}
	}
	else
		return( cESC_KEY_CANCEL );
	return( esc_code );
}

void parse_line_command(char * line_command_ptr, char * com_arg_ptr[] )	{
//puts everything in lower case and creates an array of pointers
//to the command and arguments
	unsigned char c;

	c = *line_command_ptr;
	// ignore comments, line feeds, carriage returns and 
	// null terminators for first character.
	if ( ( c == '#' ) || ( c == cASCII_CR ) || ( c == cASCII_LF ) || 
																							( c == cASCII_NULL ) )	{
		//returning a null in first pointer indicates an ignore.
			*com_arg_ptr = NULL;	
			return;
		}
	else {//get the command and arguments

		while ( ( c = *line_command_ptr ) != cASCII_NULL ) {
			//parse till end of line reached
			if ( c != cASCII_SPACE )	{//ignore leading spaces
				*com_arg_ptr++ = line_command_ptr;//point to first non null/space
				*com_arg_ptr = NULL;
						//look for next white space	or end of line
				while ( ( c != cASCII_SPACE ) && ( c != cASCII_NULL ) ) 
					c = *line_command_ptr++;
				line_command_ptr--;			//move pointer back to point to space/null
				if ( c == cASCII_SPACE )	{
					*line_command_ptr = cASCII_NULL;//replace with null termination
					line_command_ptr++;							//point to next character
				}
			}
			else
				line_command_ptr++;
		}
	}
}


void process_line_command( char * com_arg_ptr[] )	{
//execute the command
	unsigned char c;
	unsigned char i = 0;

	if ( *com_arg_ptr[ 0 ] == '?' )	{
		printStrCodeC( str_list );
		while ( command_list[ i ] != NULL )	{
			strCodecpy( com_arg_ptr[ 0 ], command_list[ i ]->command_name );
			command_list[ i ]->command_function( com_arg_ptr );
			i++;
		}
		printStrCodeC( str_Info );
	}
	else	{
		c = command_in_list( com_arg_ptr[ 0 ] );
		if ( c != cASCII_DEL )	//then execute the command function.
			command_list[ c ]->command_function( com_arg_ptr );
		else
			if ( *com_arg_ptr[ 0 ] != cASCII_NULL )
				printStrCodeC( str_unknown );
	}
}

unsigned char command_in_list( char * command_ptr )	{
//determines if the command is a valid command
	unsigned char i = 0;
	char * local_command_ptr; //need local copies
	code char * local_list_ptr;				

	while ( command_list[ i ] != NULL )	{
		local_command_ptr = command_ptr;
		local_list_ptr = command_list[ i ]->command_name;

		for ( ; *local_command_ptr == *local_list_ptr; 
							local_command_ptr++, local_list_ptr++ )
			if ( ( *local_command_ptr == cASCII_NULL ) && 
						( *local_list_ptr == cASCII_NULL ) )
				return ( i );
		i++;
	}
	return ( cASCII_DEL );	//if it gets to here there is no match.
}

//a packet command is a line command that has come over the Ethernet
//interface via CobraNet packet bridging. This will be processed like a 
//normal line command with the exception that any response is piped to
//an array to be sent back to the initiating CobraNet device.
extern void do_packet_command( char * a_command )	{
	strcpy( command_buffer, a_command );
	parse_line_command( command_buffer, command_arg_ptr );
	*a_command = cASCII_NULL;
	set_print_packet();	//make sure response is piped to memory.
	process_line_command( command_arg_ptr );
	clr_print_packet();	//return response state to normal.
}

extern unsigned char validate_hex_string( const char * hex_str_ptr, 
																				  unsigned char num_hex_char )	{
//makes sure that the hex string is valid
	const char * str_ptr;
	char c = 0;

	if ( *hex_str_ptr == cASCII_NULL )
		return ( cERR_ADDR_MISSING );
	if ( ( hex_str_ptr[ 0 ] == '0' ) && ( hex_str_ptr[ 1 ] == 'x' ) )	{
		str_ptr = hex_str_ptr + 2;//skip 0x prefix and point to rest of string
		for ( ; *str_ptr; c++, str_ptr++ )
			if ( !( isxdigit( *str_ptr ) ) )
				return( cERR_ADDR_HEX_BAD );
		if ( c > num_hex_char ) 
			return( cERR_ADDR_TOO_MANY );	//too many hex characters
	}
	else	//must be in hex format or return error, for future expansion
		return( cERR_ADDR_HEX_NOT );
	return ( 0 );	//good hex number syntax
}

extern unsigned char validate_dec_string( char * dec_str_ptr )	{
//may want to support decimal format in the future
	const char * str_ptr;

	str_ptr = dec_str_ptr;
 	for ( ; *str_ptr; str_ptr++ )
		if ( ( *str_ptr < '0' ) || ( *str_ptr > '9' ) )
			return( cERR_DECIMAL_NOT );
	return( cERR_NO_ERROR );	//good decimal number format, 
														//does not check value
}

extern unsigned char validate_ip_string( char * ip_str_ptr )	{
//validates an IP string of the format 000.000.000.000 where
//the 000 are decimal numbers. checks for max value as well
	unsigned char str_ptr[ 4 ];	//for the longest string
	unsigned char i, j;
	unsigned char err;

	if ( ip_str_ptr == NULL )
		return( cERR_MISSING_ARG );
	j = 0;
	while ( *ip_str_ptr )	{
		i = 0;
		while ( ( *ip_str_ptr != '.' ) && ( *ip_str_ptr ) && ( i < 4 ) )
			str_ptr[ i++ ]  = *ip_str_ptr++;
		str_ptr[ i ] = cASCII_NULL;
		if ( i > 3 )
			return( cERR_ADDR_TOO_MANY );
		if ( *ip_str_ptr == '.' )
			ip_str_ptr++;
		if ( err = validate_dec_string( ( char * ) str_ptr ) )
			return( err );
		if ( alpha2long( ( char * ) str_ptr ) > 255 )
			return( cERR_OUT_OF_RANGE );
		j++;
	}
	if ( j > 4 )
		return( cERR_ADDR_TOO_MANY );
	if ( j < 4 )
		return( cERR_TOO_FEW );
	return( cERR_NO_ERROR );
}

extern void make_arg_string( char * com_arg_ptr[], 
															char the_starting_point )	{
	char i = the_starting_point - 1;

	while ( com_arg_ptr[ ++i ] )
		if ( com_arg_ptr[ i + 1 ] ) //only if next is not last.
			*( com_arg_ptr[ i ] + strlen( com_arg_ptr[ i ] ) ) = ' ';
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -