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

📄 eval_cmnd.c

📁 C89c51 usb驱动程序,实现了usb转串口的功能,提供了一个虚拟的串口
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 **********************************************************************************
 *
 *  Project Name:  AT89C5131 MCU and Hi-Tech 8051 compiler evaluation
 *
 *  File Name:  eval_cmnd.c
 *
 *  Copyright 2004++ by Michael J Bauer  [www.hotkey.net.au/~mjbauer/free_IP.htm]
 *
 *  Date Created: 2004.08.26
 *
 *  This source module implements a simple "command line interface" (CLI) and a
 *  set of generic command functions, including resident "debug" facilities.
 *
 *  A command string is composed of a 2-letter command "name" and a number of
 *  user-supplied "arguments" (parameters). Some commands have no arguments.
 *  A single space must be inserted between command line arguments, where there is
 *  more than one (including the 2-letter command name).
 *  Refer to "help" strings for command syntax details.
 *
 *
 **********************************************************************************
 */

#include "a89c5131.h"        /* MCU-specific definitions */
#include "intrpt.h"          /* Compiler-specific interrupt support defs (Hi-Tech C 8051) */
#include "eval_defs.h"       /* Eval common definitions */
#include "usb_vuart_lib.h"
#include "usb_drv.h"
#include "usb_cdc_enum.h"


/* Command table entry looks like this */
struct  CmndTableEntry_t
{
	char     cName1;			/* command name, 1st char */
	char     cName2;			/* command name, 2nd char */
	pfnvoid  Function;			/* pointer to CLI function */
};


/***  globals  ***/
idata  char    gacCmdLine[CMD_LINE_SIZE];     /* Command Line buffer for USB input */
idata  char  * pacCmdLinePtr;                /* Pointer into gacCmdLine[] */
idata  char    gacPrompt[6];                 /* Variable prompt string */
idata  uint8   gubRespCksm;           		 /* Response checksum (1 byte) */


/*****
*	Text strings for "help" command.
*/
const  char  kszHelpPage1[] = "User command set...\n" ;
const  char  kszHelpHE[] = "HE [+]     | Help (+ debug cmnds)\n" ;
const  char  kszHelpST[] = "ST <arg>   | Set Time & date (arg='yymmdd-hhmmss')\n" ;
const  char  kszHelpDP[] = "DP         | Default Param's\n" ;
const  char  kszHelpWA[] = "WA         | Watch Variables\n" ;
const  char  kszHelpWT[] = "WT         | Watch Timers\n" ;
const  char  kszHelpSE[] = "SE         | System Errors\n" ;
const  char  kszHelpVN[] = "VN         | Firmware Version\n" ;
const  char  kszHelpRS[] = "RS         | Reset \n" ;

const  char  kszHelpPage2[] = "Debug command set...\n" ;
#if  DISASM_INCLUDED
const  char  kszHelp202[] = "DA aaaa x  | Disassemble @ aaaa [x= no pause]\n" ;
#endif
const  char  kszHelp203[] = "DC [aaaa]  | Dump Code memory (0000..FFFF)\n" ;
const  char  kszHelp204[] = "DD [aaaa]  | Dump Data memory (0000..FFFF)\n" ;
const  char  kszHelp205[] = "DE p       | Dump EEPROM page (0..7)\n" ;
const  char  kszHelp206[] = "RM aa      | Read  MCU memory (00..FF)\n" ;
const  char  kszHelp207[] = "WM aa dd   | Write MCU memory (00..FF)\n" ;
const  char  kszHelp208[] = "RP p.b     | Read  Port pin   (p=0..3, b=0..7)\n" ;
const  char  kszHelp209[] = "WP p.b d   | Write Port latch (p=0..3, d=0,1)\n" ;
const  char  kszHelp210[] = "RE aaaa    | Read  Ext memory or I/O\n" ;
const  char  kszHelp211[] = "WE aaaa dd | Write Ext memory or I/O\n" ;
const  char  kszHelp212[] = "XE aaaa    | Execute function\n" ;


/*****
*	String constants...
*	(See comments with function putconstr() elsewhere in this module.)
*/
const  char  kszGreeting[] = "AT89C5131 Evaluation Firmware: ";
const  char  kszCopyright[] = "M.J. Bauer 2004";
const  char  kszHead16bits[] = "15-------10 9 8   7 6 5 4 3 2 1 0 \n";
const  char  kszCommandError[] = "Command error!\n";

const  char  kszWatchAppHeader[]
             = "Hit <Enter> to quit...\n";
const  char  kszWatchTimHeader[]
             = "_____Date_____  __Time__  _______________\n";

const  char  kszSUN[] = "SUN";
const  char  kszMON[] = "MON";
const  char  kszTUE[] = "TUE";
const  char  kszWED[] = "WED";
const  char  kszTHU[] = "THU";
const  char  kszFRI[] = "FRI";
const  char  kszSAT[] = "SAT";

const  char * pkzDayName[] = { kszSUN, kszMON, kszTUE, kszWED, kszTHU, kszFRI, kszSAT };

const  char  kszTimeInvalid[] = "--:--:--";


/*****
*	Command table -- maximum number of commands is 250.
*   (Application-specific command functions should go at the top)
*/
const  struct  CmndTableEntry_t  asCommand[] =
{
	'H','E',	help_cmd,             /* "User" commands */
	'S','T',	show_set_time_cmd,
	'W','T',	watch_timers_cmd,
	'W','A',	watch_app_cmd,
	'D','P',    default_params_cmd,
	'S','E',	show_errors_cmd,
	'V','N',	version_cmd,
	'R','S',	reset_MCU_cmd,
#if  DISASM_INCLUDED
	'D','A',	disassemble_cmd,      /* "Debug" commands */
#endif
	'D','C',	dump_memory_cmd,
	'D','D',	dump_memory_cmd,
	'D','E',	dump_memory_cmd,
	'R','M',	read_MCU_mem_cmd,
	'W','M',	write_MCU_mem_cmd,
	'R','P',	read_port_cmd,
	'W','P',	write_port_cmd,
	'R','E',	read_extd_cmd,
	'W','E',	write_extd_cmd,
	'X','E',	execute_cmd,
	'$','$',	DummyCmd		      /* Last entry in cmd table */
} ;


/**********************************  CLI FUNCTIONS  **************************************/

/*****
*	Initialise the Command Line Interface
*	Called from main before CLI is used.
*   CLI functions may change gacPrompt[0] or gacPrompt[1] to indicate various conditions,
*   e.g. errors, warnings, other command status.
*/
void
initialise_cli()
{
	gbHCI_Stream = UART_HOST_LINK;	 // default HCI input/output stream
	
	gacPrompt[0] = '-';              /* Create prompt string */
	gacPrompt[1] = '-';
	gacPrompt[2] = '>';
	gacPrompt[3] = SPACE;
	gacPrompt[4] = NUL;
	
	flush_command_line();
}



/*****
*	Function:	check_HCI_input
*	Purpose:	Host command interface (HCI) data input routine for UART.
*
*	This background function is called *frequently* from the main loop. It is not a
*	"scheduled" task, and therefore it is permitted to call the function 'putch()'.
*	The function checks for data input from the host PC via the UART; it returns 
*	immediately if there's no new input data available from the active input stream.
*
*	If there is data available, it is processed. Printable chars are appended to the
*	command line buffer. The same buffer is common to UART and USB input streams.
*	Only data from the active input stream is written into the command line buffer.
*
*	When a command terminator (CR) is received, the command line is interpreted and if 
*	the cmnd name is defined, the respective command function is executed.
*	Most command functions generate response data to be output to the host PC.
*	Output data is directed to the port associated with the active input/output stream.
*	A global variable determines the active input/output stream (UART or USB).
*
*	If 3 successive 'SYN' codes (Ctrl-V = ASCII 22) are received from the same input
*	stream, then that stream will become the active one. 
*/
void
check_uart_HCI_input( void )
{
	static  uint8  bUART_SYNcount;		// Number of 'SYN' codes rx'd from UART input stream
	char   c; 

	if ( uart_rx_data_avail() )
	{
		c = uart_getch();						// no echo yet (in case c==SYN)
		if ( gbHCI_Stream == UART_HOST_LINK )
		{
			putch( c );   						// echo char to HCI stream
			process_HCI_input_char( c );
		}
		else if ( c == SYN )
		{
			if ( ++bUART_SYNcount >= 3 )		
			{
				gbHCI_Stream = UART_HOST_LINK;		// make UART the active I/O stream
				bUART_SYNcount = 0;
				flush_command_line();
				put_prompt();
			}
		}
		else  bUART_SYNcount = 0;
	}
}


/*****
*	Function:	check_usb_HCI_input
*	Purpose:  	Host command interface (HCI) data input routine for USB port.
*
*	Performs the same routine as check_uart_HCI_input(), above, but with USB input.
*	See header on check_uart_HCI_input().
*/
void
check_usb_HCI_input( void )
{
	static  uint8  bUSB_SYNcount;		// Number of 'SYN' codes rx'd from USB input stream
	char   c; 

	if ( usb_vuart_rx_data_avail() )
	{
		c = usb_vuart_getchar();			// no echo yet
		if ( gbHCI_Stream == USB_HOST_LINK )
		{
			putch( c );   					// echo char to HCI stream...
			usb_vuart_flush();				// ... immediately (if diagnostic mode)
			process_HCI_input_char( c );
		}
		else if ( c == SYN )
		{
			if ( ++bUSB_SYNcount >= 3 )		// make USB the active I/O stream
			{
				gbHCI_Stream = USB_HOST_LINK;
				bUSB_SYNcount = 0;
				flush_command_line();
				put_prompt();
			}
		}
		else  bUSB_SYNcount = 0;
	}
}


/*****
*	Function common to both check_uart_HCI_input() and check_usb_HCI_input().
*	Examines a character received via the active input stream and decides what
*	to do with it. If printable, it goes into the command line buffer, gacCmdLine[].
*/
void
process_HCI_input_char( char c )
{
	if ( c == CR )		// CR is the command line terminator
	{
		if ( pacCmdLinePtr != gacCmdLine )	/* Cmd line length > 0 */
			do_command();
		else  { putNewLine();  put_prompt(); }
	}
	else if ( isprint(c) )		// if printable, append c to command line
	{
		if ( pacCmdLinePtr <= (gacCmdLine + CMD_LINE_SIZE - 2) )
			{ *pacCmdLinePtr++ = c;  *pacCmdLinePtr = NUL; }
	}
	else if ( c == ESC || c == BACKSP )		/* Trash cmd line */
	{
		flush_command_line();
		gacPrompt[1] = '?';
		putch( NUL );
		putNewLine();
		put_prompt();
	}
}


/*
*	Function:	do_command
*
*	Purpose:
*	Looks for command name (mnemonic, 2 chars) in command table;
*	if found, executes respective command function.
*	Output is directed to the active HCI stream (USB or UART).
*/
void
do_command( void )
{
	char   c1, c2;
	uint8  n;
	bool   yFoundCndName = FALSE;

	c1 = toupper( gacCmdLine[0] );
	c2 = toupper( gacCmdLine[1] );
	gubRespCksm = 0;
	
	for ( n = 0;  n < 250;  n++ )
	{
		if ( asCommand[n].cName1 == '$' )  		/* end of table */
			break;
		if ( asCommand[n].cName1 == c1 )
		{
			if ( asCommand[n].cName2 == c2 )		/* found match */
			{
				yFoundCndName = TRUE;
				break;
			}
		}
	}
	putNewLine();
	if ( yFoundCndName )
		(*asCommand[n].Function)();		/* Call CLI command function */
	else  
	{
		putconstr( kszCommandError );
		gacPrompt[1] = '?';             /* NACK... unrecognised command */
	}
	put_prompt();
	flush_command_line();
}


/*****
*   Function:	flush_command_line();
*	Clear command line buffer and reset pointer.
*
*   Param's:  --
*   Returns:  --
*   Globals:  pacCmdLinePtr, gacCmdLine
*/
void
flush_command_line( void )
{
	uint8  ubx;

	for ( ubx = 0;  ubx < CMD_LINE_SIZE;  ubx++ )
	{
		gacCmdLine[ubx] = NUL;
	}
	pacCmdLinePtr = gacCmdLine;
}


/*
*  Output the prompt string to active HCI stream.
*  If the HCI stream is USB, then the USB TX buffer is flushed (transmitted to the host)
*  so that the prompt is seen at the host immediately.
*/
void
put_prompt( void )
{
	putstr( gacPrompt );
	if ( gbHCI_Stream == USB_HOST_LINK )  usb_vuart_flush();
	gacPrompt[0] = '-';    // restore prompt
	gacPrompt[1] = '-';
}


/*  Dummy command function -- does nothing!  */
void
DummyCmd( void )
{
	return;
}



/******************************  "USER" COMMAND FUNCTIONS  ********************************
*
*
*  Command function 'HE' :  Outputs a list of available commands & their param's.
*
*  Command line format:  "HE [+]"
*  Optional parameter [+] selects "debug" commands page.
*  User commands are selected by default.
*/
void
help_cmd( void )
{
	if ( gacCmdLine[2] == SPACE )	/* Cmnd line arg. supplied... */
	{
		putconstr( kszHelpPage2 );   /* List debug command set */
#if  DISASM_INCLUDED
		putconstr( kszHelp202 );
#endif
		putconstr( kszHelp203 );
		putconstr( kszHelp204 );
		putconstr( kszHelp205 );
		putconstr( kszHelp206 );
		putconstr( kszHelp207 );
		putconstr( kszHelp208 );
		putconstr( kszHelp209 );
		putconstr( kszHelp210 );
		putconstr( kszHelp211 );
		putconstr( kszHelp212 );
	}
	else		/* No cmd line arg. */
	{
		putconstr( kszHelpPage1 );    /* List end-user command set */
		putconstr( kszHelpHE );
		putconstr( kszHelpST );
		putconstr( kszHelpWT );
		putconstr( kszHelpWA );
		putconstr( kszHelpDP );
		putconstr( kszHelpSE );
		putconstr( kszHelpVN );
		putconstr( kszHelpRS );
	}
}


/*
*  Command function 'ST':  Show or Set RTC Time and date.
*  Cmd format: "ST yymmdd.hhmmss"  (Time is in 24 hour format)
*  If the argument [yymmdd.hhmmss] is omitted, the function outputs the date & time.
*  (See also: watch_timers_cmd() function.)
*/
void
show_set_time_cmd( void )
{
	if ( !isdigit( gacCmdLine[3] )      /* No arg, or format error... */
	||   !isdigit( gacCmdLine[10] )
	||   gacCmdLine[2] != SPACE   )
	{									/* Show current RTC date:time */
		read_RTC_date_time();
		putch( ' ' );
		putconstr( pkzDayName[gsRTCbuf.dow] );
		putch( SPACE );
		putch( '2' ); putch( '0' );
		putDecimal( gsRTCbuf.year, 2 );
		putch( '.' );
		putDecimal( gsRTCbuf.month, 2 );
		putch( '.' );
		putDecimal( gsRTCbuf.day, 2 );
		putch( SPACE );
		putch( SPACE );
		putDecimal( gsRTCbuf.hour, 2 );
		putch( ':' );
		putDecimal( gsRTCbuf.min, 2 );
		putch( ':' );
		putDecimal( gsRTCbuf.sec, 2 );
		putNewLine();
	}
	else
	{
		gsRTCbuf.year  = decatoi( &gacCmdLine[3], 2 );
		gsRTCbuf.month = decatoi( &gacCmdLine[5], 2 );
	  	gsRTCbuf.day   = decatoi( &gacCmdLine[7], 2 );
	  	gsRTCbuf.hour  = decatoi( &gacCmdLine[10], 2 );
		gsRTCbuf.min   = decatoi( &gacCmdLine[12], 2 );
		gsRTCbuf.sec   = decatoi( &gacCmdLine[14], 2 );

		set_RTC_date_time();		/* This also determines the "day of the week" value */

		if ( read_RTC_date_time() )					/* success! */
			Clear_Bit( gwSystemError, RTC_INVALID );
	}
}


/*
*  Command function 'WT':  Watch Timers (in real time).
*  Outputs RTC day-date-time and various system timers in ASCII format.
*  The output line is continuously refreshed until a char is received from
*  the host PC (i.e. any key hit).
*/
void
watch_timers_cmd( void )
{
	uint16  wStartTime;
	
	putconstr( kszWatchTimHeader );
	while ( 1 )    /* Loop until any key hit */
	{
		read_RTC_date_time();
		putconstr( pkzDayName[gsRTCbuf.dow] );
		putch( SPACE );  
		putch( '2' );  putch( '0' );
		putDecimal( gsRTCbuf.year, 2 );
		putch( '.' );
		putDecimal( gsRTCbuf.month, 2 );
		putch( '.' );
		putDecimal( gsRTCbuf.day, 2 );
		putch( SPACE );
		putch( SPACE );
		putDecimal( gsRTCbuf.hour, 2 );
		putch( ':' );
		putDecimal( gsRTCbuf.min, 2 );
		putch( ':' );
		putDecimal( gsRTCbuf.sec, 2 );
		putch( SPACE );
		putch( SPACE );
		if ( gbHCI_Stream == USB_HOST_LINK )  usb_vuart_flush();
		wStartTime = get_ticks();
		while ( get_ticks() - wStartTime < 10 )		// wait 50mS (10 ticks)
		{
			background_process();
		}
		putch( CR );
		if ( hci_data_avail() )  { getch();  break; }   // quit
	}
	putNewLine();
}


/*
*  Command function 'WA':  Watch Application variables in real-time.
*  (See 'WT' cmd fn for a complete example of implementation.)
*/
void
watch_app_cmd( void )
{
	uint16  wStartTime;
	
	putconstr( kszWatchAppHeader );		// Output a header line (optional)
	
	while ( 1 )    /* Loop until any key hit */
	{
		/**** Output app. variables here on a single line *****/


		if ( gbHCI_Stream == USB_HOST_LINK )  usb_vuart_flush();
		wStartTime = get_ticks();
		while ( get_ticks() - wStartTime < 10 )		// wait 50mS (10 ticks)
		{
			background_process();
		}
		putch( CR );
		if ( hci_data_avail() )  { getch();  break; }   // quit
	}
	putNewLine();
}


/*
*  Command function 'DP':  Default configuration parameters.
*
*  Configuration parameters are application-specific persistent data maintained in EEPROM.
*  The command copies "factory default" parameter values from program code ('const' data) 
*  to ERAM working variables, then stores these in a pre-defined EEPROM page.
*
*  The example given here simply copies some strings from program code to ERAM and EEPROM,
*  in order to demonstrate the EEPROM handling functions built into the operating system.
*  The command 'DE 0' may be used to verify the operation.
*

⌨️ 快捷键说明

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