📄 eval_main.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 + -