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

📄 eval_main.c

📁 C89c51 usb驱动程序,实现了usb转串口的功能,提供了一个虚拟的串口
💻 C
字号:
/*
 **********************************************************************************
 *
 *  Project Name:  AT89C5131 MCU and Hi-Tech 8051 compiler evaluation
 *
 *  File Name:  eval_main.c
 *
 *  Copyright 2004++ by Michael J Bauer  [www.hotkey.net.au/~mjbauer]
 *
 *  Date Created: 2004.08.26
 *
 *  Firmware Functional Description:
 *
 *  This AT89C5131 MCU application program runs on the AT89-05SDK evaluation board
 *  (and compatible clones like the one designed by the author).
 *
 *  The program implements a simple embedded RTOS with resident debugging facilities,
 *	using a command-line user interface (CLI) accessible via the UART or USB port.
 *
 *  The firmware incorporates USB library modules supplied by Atmel Corp (with minor mods).
 *	The USB library source code has been adapted to suit the HI-TECH C-8051 compiler.
 *
 *  If using the USB port, the host PC needs a suitable USB device driver.
 *  A standard USB "Communications Device Class" (CDC) driver should allow a "virtual" COM
 *  port to be configured for use with any PC application (e.g. HyperTerminal).
 *  MS Windows 98SE/98ME, 2000 and XP all have a built-in USB 'CDC' driver.
 *	A driver information file (c5131_cdc.inf) is provided by Atmel for device installation.
 *
 *	The CLI is accessible from either the USB port or the "RS-232" async serial port (UART),
 *  online switchable. A PC terminal emulator application (e.g. HyperTerminal) can be used to
 *  access the CLI via the USB port. The terminal emulator will need to be configured to use
 *  a "virtual" COM port, which should manifest itself when a USB connection has been made.
 *
 *  To switch the "HCI serial I/O stream" (host port) from USB ot UART, or vice-versa, the
 *  host sends 3 ASCII 'SYN' chars (Ctrl+V) in succession. This will set the HCI I/O stream to
 *  the source of the 'SYN' codes.
 *  The CLI could be easily adapted to support "simultaneous" usage of both USB and UART,
 *  by providing separate command line input buffers for each stream.
 *
 *
 *  Compiler:     	Hi-Tech C 8051 V9.01 with HI-TIDE V2.13 (free demo version)
 *	Options:		HI-TIDE defaults.
 *  Memory model: 	Small
 *
 *
 *           ------ REVISION HISTORY -------
 *
 *	V1.00  2004.09.02	Basic embedded RTOS with CLI debug facilities...
 *                      Host PC comm's is via UART only (no USB support)
 *						(This version will run on any 8051 MCU)
 *
 *	V2.00  2004.09.09	Basic embedded RTOS with CLI debug facilities...
 *                      Host PC comm's is via USB or UART (switchable)
 *
 *	V2.20  2005.01.14	Added on-chip EEPROM support;  added LED drivers.
 *
 ***********************************************************************************
 */

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

const  char  kszVersion[]  = "V2.30";       /* Firmware version ID */

/*
*	globals
*/
idata  bit    yUSB_connected;
idata  uint8  bUSB_SOFcounter;
idata  uint8  bLastTxCounter;

extern uint8  usb_configuration_nb;
extern uint8  tx_counter;

far  uint8  ghabParam[MAX_PARAMS];       /* Parameter array, persistent data */



/*****
*	Function to initialise application program variables, etc.
*/
void
initialise_app( void )
{
	uint16  wStartTime = get_ticks();

	configure_usb_clock();
	Usb_enable();
	Usb_detach();
	while ( get_ticks() - wStartTime < 10 )		// wait 50mS
	{
		service_watchdog();
	}
	Usb_attach();
	usb_configure_endpoint( EP_CONTROL, CONTROL );
	usb_reset_endpoint( EP_CONTROL );
	usb_var_init();
	usb_vuart_init();
	bLastTxCounter = 0;
	yUSB_connected = TRUE;

	fetch_persistent_data();    /* ... if using EEPROM  */
}


/*********************************  MAINLINE  ********************************************
*
*   Do initialisation.
*   Set LED_0 pulsing at 1Hz... "heartbeat" indication.
*   Launch the main background loop.
*/
void
main( void )
{
	initialise_rtos();
	initialise_cli();
	initialise_app();
	
	SetLEDFlashMode( LED_0, TIME_1000mS, TIME_100mS );
	putNewLine();
	version_cmd();
	put_prompt();

	while ( 1 )
	{
		maintain_usb_connection();
		background_process();
		check_uart_HCI_input();
		check_usb_HCI_input();
	}
}


/*****
*	Function:	maintain_usb_connection
*	Purpose:	maintain USB connection
*/
void
maintain_usb_connection(void)
{
	if ( ! yUSB_connected )
	{
		if ( Usb_resume() )
		{
			Usb_clear_suspend_clock();
			yUSB_connected = TRUE;
			Usb_clear_suspend();
			Usb_clear_resume();
			Usb_clear_sof();
		}
	}
	else
	{
		if ( Usb_suspend() )
		{
			yUSB_connected = FALSE;
			Usb_clear_suspend();
			Usb_set_suspend_clock();
		}
		if ( Usb_reset() )
		{
			usb_var_init();
			Usb_clear_reset();
			usb_vuart_init();
			bLastTxCounter = 0;
		}
		if ( Usb_sof() )
		{
			if ( bLastTxCounter == tx_counter ) usb_vuart_flush();	// check
			bLastTxCounter = tx_counter;
			bUSB_SOFcounter++ ;
			Usb_clear_sof();
		}
		if ( Usb_endpoint_interrupt() )		// polling, not a real interrupt
		{
			Usb_select_ep( EP_CONTROL );
			if ( Usb_setup_received() )  usb_enumeration_process();
			Usb_select_ep( 3 );
			if ( Usb_tx_complete() )  Usb_clear_tx_complete();
		}
	}
}



/******************************************************************************************
*
*	Function:		background_process  
*	Purpose:		Background task dispatcher for scheduled tasks.
*	Called from:	main background loop
*
*	The background process consists of a number of tasks which may be executed periodically
*	or "ad-hoc" (i.e. invoked by another process). Periodic tasks are scheduled by the RTI
*	timer "tick handler" (foreground routine). B/G tasks are not prioritised in this
*	minimal RTOS design... pending tasks are executed in a round-robin loop.
*
*	The background process should normally be completed within 5 mSec (tick interval),
*	although the occasional *brief* overrun can be tolerated, as long as the overrun time
*	does not exceed the watchdog time-out interval.
*
*	The background process and all functions which it calls are prohibited from
*   calling functions which input data via "getch()" or which output data via "putch()".
*   This is because getch() and putch() call the background process, so that command functions
*   which use getch() or putch() do not cause delays to background tasks during serial I/O.
*/
void
background_process( void )
{
	if ( Test_Bit( gubTaskFlags, TICKS_TASK ) )			/* Flag set every tick (5 mSec) */
	{
		#if WATCHDOG_ENABLED
			service_watchdog();
		#endif

		/*** Put here calls to function(s) to be executed every tick (5 mSec) ***/
		
		Clear_Bit( gubTaskFlags, TICKS_TASK );
	}
	if ( Test_Bit( gubTaskFlags, FIFTY_MSEC_TASK ) )	/* Flag set every 10th tick (50 mSec) */
	{
		/*** Put here calls to function(s) to be executed every 50mSec ***/
		
		Clear_Bit( gubTaskFlags, FIFTY_MSEC_TASK );
	}
	if ( Test_Bit( gubTaskFlags, SECONDS_TASK ) )		/* Flag set every second */
	{
		/*** Put here calls to function(s) to be executed every second ***/
		
		Clear_Bit( gubTaskFlags, SECONDS_TASK );
	}
	if ( Test_Bit( gubTaskFlags, NEWDAY_TASK ) )		/* Flag set every day at mid-night */
	{
		/*** Put here calls to function(s) to be executed every day at midnight ***/
		
		Clear_Bit( gubTaskFlags, NEWDAY_TASK );
	}
	
	if ( Test_Bit( gubTaskFlags, EEPROM_UPD_TASK ) )    /* Flag set to store data in EEPROM */
		eeprom_update_task();
		
	/*** Put here conditional calls to any other task functions ***/
}




/**************************  EEPROM DATA HANDLING FUNCTIONS  ********************************
*   
*   Below is a suite of generic functions designed for systematic handling of non-volatile
*   data, e.g. application configuration parameters and any other persistent data to be
*   stored in the 1kB EEPROM data block (MCU on-chip data EEPROM).
*   These functions are intended to be customised to suit the application.
*
*
*   Function:  fetch_persistent_data
*   Called by initialise_app() in main module (and perhaps elsewhere).
*
*   Copies persistent data from EEPROM to respective working variables in extd RAM.
*   The data to be copied should be in pre-defined arrays or structures.
*   In this example, configuration param's are read into an array in ERAM - ghabParam[].
*   In this example, only page 0 of EEPROM is used, so ghabParam[] <= 128 bytes.
*/
void
fetch_persistent_data( void )
{
	eeprom_read_data( habEEPROM_page0, ghabParam, MAX_PARAMS );
}


/*
*   Function:  eeprom_update_task  (Ad-hoc Background task)
*
*   Copies "persistent" data from extd RAM (working variables) to EEPROM.
*   The page(s) to be updated is/are selected by a private static variable, hbEEPageSel,
*   which has one bit assigned to each of the 8 EEPROM pages (bit0 => page 0, etc).
*   Refer to eval_defs.h for persistent data declarations.
*
*   The function initiates an EEPROM programming cycle in one selected EEPROM page.
*   When all selected pages have been updated, the task suspends itself.
*   The task is invoked (e.g.) by store_persistent_data(), and/or similar custom functions.
*
*   The task first checks that the EEPROM is not busy (i.e. not already programming);
*   if the EEPROM is busy, the task is deferred, i.e. it returns immediately, but remains 
*   active so that the data will be stored on a subsequent call (when EEPROM not busy).
*/
static  far uint8  hbEEPageSel;    /* Page select:  Bit0 => Page0; Bit1 => Page1; etc */

void
eeprom_update_task( void )
{
	uint8  bByteCount;
	far uint8 * phbXRAMptr;
	far uint8 * phbEEPROMptr;

	if ( eeprom_busy() )  return;     /* Defer task until EEPROM is ready */

	if ( hbEEPageSel & BIT0 )         /* Page 0 selected for update */
	{
		eeprom_write_data( habEEPROM_page0, ghabParam, MAX_PARAMS );
		hbEEPageSel &= ~BIT0;
		eeprom_start_prog();
	}
	else if ( hbEEPageSel & BIT1 )    /* Page 1 selected for update */
	{
		/* Setup pointers and bytecount as for page 0, if page 1 needed */

		eeprom_write_data( phbEEPROMptr, phbXRAMptr, bByteCount );
		hbEEPageSel &= ~BIT1;
		eeprom_start_prog();
	}
	else if ( hbEEPageSel & BIT2 )    /* Page 2 selected for update */
	{
		/* Setup pointers and bytecount as for page 0, if page 2 needed */

		eeprom_write_data( phbEEPROMptr, phbXRAMptr, bByteCount );
		hbEEPageSel &= ~BIT2;
		eeprom_start_prog();
	}

	/*** Extend "else if" chain for other EEPROM pages, as required. ***/
	

	/*** Finally, test for all selected pages updated... if so, clear task flag... ***/
	if ( hbEEPageSel == 0 )  Clear_Bit( gubTaskFlags, EEPROM_UPD_TASK );    /* Task done */
}


/*
*   Function:  store_persistent_data
*
*   Triggers a background task to update one or more EEPROM page(s).
*   Page 0 contains, for example, configuration parameters for the application.
*   Similar functions may be created to update other EEPROM pages, as required by the
*   application. Alternatively, a single function can be used to update all pages in use.
*/
void
store_persistent_data( void )
{
	hbEEPageSel |= BIT0;        /* Select EEPROM page 0 for update */
/*	hbEEPageSel |= BIT1;  */    /* Select EEPROM page 1 for update */ 
/*	hbEEPageSel |= BIT2;  */    /* Select EEPROM page 2 for update */

	Set_Bit( gubTaskFlags, EEPROM_UPD_TASK );    /* Activate B/G task */
}


/*** end ***/

⌨️ 快捷键说明

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