📄 example.c
字号:
/*
* example.c
*
* Main module with example functions for USB comm's with "virtual UART".
*/
#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"
/*
* Function prototypes -- better to be put in a header file
*/
void transmit_data_to_host( void );
void usb_putstr( char * psz );
void usb_putHexdigit( uint8 d );
void usb_putHexbyte( uint8 b );
void usb_putHexword( uint16 uwArg1 );
void usb_putDecimal( uint16 uwArg1, uint8 ubPlaces );
/*
* globals
*/
idata bit yUSB_connected;
idata uint8 bUSB_SOFcounter;
idata uint8 bLastTxCounter;
extern uint8 usb_configuration_nb;
extern uint8 tx_counter;
/*****
* 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 < 100 ) // wait 500mS
{
;;;
}
Usb_attach();
usb_configure_endpoint( EP_CONTROL, CONTROL );
usb_reset_endpoint( EP_CONTROL );
usb_var_init();
usb_vuart_init();
bLastTxCounter = 0;
yUSB_connected = TRUE;
}
/********************************* MAINLINE ********************************************
*
*/
void
main( void )
{
initialise_rtos();
initialise_cli();
initialise_app();
while ( 1 ) // main loop
{
maintain_usb_connection();
background_process();
check_uart_HCI_input(); // Using UART (RS232) for CLI "debug port"
/***
check_usb_HCI_input(); // Disabled!!! Not using USB for CLI!!!
***/
}
}
/*****
* Function: maintain_usb_connection
* Purpose: maintain USB connection
*
* Must be called *frequently* from main loop!
*/
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 ***/
transmit_data_to_host(); // Application-specific task
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 ***/
}
/*
* Function to transmit data to host PC via USB virtual uart.
* This is a scheduled task, called by the background_process() "task dispatcher",
* once every second.
*
* In this example, a 16-bit binary number is converted to a decimal ASCII string
* and output via the USB "vuart" by the function usb_putDecimal(), defined below.
* The number is incremented each time, so it will count up in seconds.
*/
void transmit_data_to_host( void )
{
static uint16 counter; // The number to be output
usb_putDecimal( counter, 5 ); // Output number as decimal ASCII (write to USB buffer)
usb_vuart_putchar('\r'); // Output CR, stay on same line
usb_vuart_flush(); // Transmit the USB buffer contents now
counter++ ;
}
/*________________________________________________________________________________________*\
*
* The functions below comprise an extension to the "USB VUART I/O library".
* These functions implement ASCII formatted output of data to the host PC.
\*________________________________________________________________________________________*/
/*
* Output NUL-terminated string, i.e. "near" or "idata" char array, in page zero RAM.
* The string must be stored in the MCU internal RAM page zero (address range 00..FF).
* Using the compiler Small Memory Model (recommended), variables which are not
* explicitly declared "far" or "const" will be allocated to page zero RAM.
*
* Newline (0x0A) is expanded to CR + LF (0x0D + 0x0A) and the USB TX buffer is flushed.
*
* Called by: background tasks
* Entry args: psz = address of NUL-terminated string in page zero RAM.
* Returns: --
* Affects: --
*/
void usb_putstr( char * psz )
{
char c;
while ( (c = *psz++) != NUL )
{
if ( c == 0x0A )
{
usb_vuart_putchar( CR );
usb_vuart_putchar( LF );
usb_vuart_flush();
}
else usb_vuart_putchar( c );
}
}
/*
* Output 4 LS bits of a byte as Hex (or BCD) ASCII char.
*
* Called by: background tasks
* Entry args: d = value of Hex digit (0 to 0xf)
* Returns: void
* Affects: --
*/
void usb_putHexdigit( uint8 d )
{
d &= 0x0F;
if ( d < 10 ) usb_vuart_putchar( '0' + d );
else usb_vuart_putchar( 'A' + d - 10 );
}
/*
* Output byte as 2 Hex ASCII chars, MSD first.
*
* Called by: background tasks
* Entry args: b = byte to output
* Returns: void
* Affects: --
*/
void usb_putHexbyte( uint8 b )
{
usb_putHexdigit( b >> 4 );
usb_putHexdigit( b );
}
/*
* Output 16-bit word as 4 Hex ASCII chars, MSD first.
*
* Called by: background tasks
* Entry args: uwArg1 = word to output
* Returns: void
* Affects: --
*/
void usb_putHexword( uint16 uwArg1 )
{
usb_putHexdigit( (uint8) (uwArg1 >> 12) );
usb_putHexdigit( (uint8) (uwArg1 >> 8) );
usb_putHexdigit( (uint8) (uwArg1 >> 4) );
usb_putHexdigit( (uint8) (uwArg1 & 0xF) );
}
/*
* Output a 16-bit unsigned word as an ASCII decimal number.
* The number of digit places to be output (1 to 5) is specified as a parameter.
* If the decimal word value is larger than can fit into the number of places
* specified, then the output will be truncated to the least significant digit(s).
* If the decimal word value is smaller than can occupy the number of places
* specified, then the output will be padded with leading 0's.
*
*
* Called by: background tasks
* Entry args: (uint16) uwArg1 = word to output
* (uint8) ubPlaces = number of digit places to output (1..5)
* Returns: void
* Affects: --
*/
void usb_putDecimal( uint16 uwArg1, uint8 ubPlaces )
{
int8 bPos;
uint8 aubDigit[5]; /* BCD result, 1 byte for each digit */
if ( ubPlaces > 5 ) ubPlaces = 5;
for ( bPos = 4; bPos >= 0; --bPos )
{
aubDigit[bPos] = uwArg1 % 10;
uwArg1 /= 10;
}
for ( bPos = 5 - ubPlaces; bPos < 5; ++bPos )
usb_putHexdigit( aubDigit[bPos] );
}
/*** end ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -