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

📄 usb_main.c

📁 USB CDC using C8051F320/340, virtual COM port thru usb connection
💻 C
字号:
//-----------------------------------------------------------------------------
// USB_Main.c
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include "USB_Type.h"
#include "USB_Configuration.h"
#include "USB_Register.h"
#include "USB_Descriptor.h"
#include "USB_Standard_Requests.h"
#include "USB_ISR.h"
#include "USB_CDC_UART.h"
#include "FIFO_RW.h"
#include "USB_Main.h"

#if defined KEIL
#include <intrins.h>						// for _testbit_(), _nop_()
#endif // KEIL

//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------

#if defined C8051F320_H
	#define SYSCLK	24000000L				// SYSCLK frequency in Hz
#endif
#if defined C8051F340_H
	#define SYSCLK	48000000L				// SYSCLK frequency in Hz
#endif

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------

#if defined KEIL

sfr16 TMR2RL	= 0xca;					// Timer2 reload value
sfr16 TMR2		= 0xcc;					// Timer2 counter

#endif // KEIL

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

// port assignment

#if defined KEIL

sbit Sw1  = P2^0;
sbit Sw2  = P2^1;
sbit Led1 = P2^2;							// LED='1' means ON
sbit Led2 = P2^3;

#endif // KEIL

#if defined SDCC

#define Sw1		P2_0
#define Sw2		P2_1
#define Led1	P2_2						// LED='1' means ON
#define Led2	P2_3

#endif // SDCC

static bit Switch1State = FALSE;			// Indicate status of switch
static bit Switch2State = FALSE;			// starting at 0 == off

static bit Toggle1 = FALSE;					// Variable to make sure each button
static bit Toggle2 = FALSE;					// press and release toggles switch

volatile bit switch_changed = FALSE;


//-----------------------------------------------------------------------------
// Static variables in this file
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Local Prototypes
//-----------------------------------------------------------------------------

// Initialization Routines
void Sysclk_Init(void);						// Initialize the system clock
void Port_Init(void);						// Configure ports
void Timer_Init(void);						// Timer 2 for use by ADC and swtiches

//-----------------------------------------------------------------------------
// ISR prototype
//-----------------------------------------------------------------------------
#if defined SDCC

extern void Usb_ISR(void) interrupt 8;
extern void Timer2_ISR(void) interrupt 5;

#endif	// SDCC

//------------------------------------------------------------------------
// startup routine
//------------------------------------------------------------------------

#if defined SDCC

unsigned char _sdcc_external_startup ( void )
{
   PCA0MD &= ~0x40;							// Disable Watchdog timer
   return 0;
}

#endif	// SDCC


//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void)
{
#if defined KEIL
	PCA0MD &= ~0x40;						// Disable Watchdog timer temporarily
#endif // KEIL
	Sysclk_Init();							// Initialize oscillator
	Port_Init();							// Initialize crossbar and GPIO
	Timer_Init();							// Initialize timer2
	Flush_COMbuffers();						// Initialize COM ring buffer
	Led1 = FALSE;
	Led2 = FALSE;
	Usb0_Init();							// Initialize USB0 - at the end of initizaliation

	EIE1	|= 0x02;						// Enable USB0 interrupt
	IE		|= 0xA0;						// Enable Timer2 and Global Interrupt enable


	while ( 1 ) {							// main loop

		{									// task1 - CDC support
			BYTE dt;
			BYTE line_state;

			CDC_Handle_Bulk_IN();				// Poll IN/OUT EP2 and handle transaction
			CDC_Handle_Bulk_OUT();

			if ( switch_changed )				// Reflect the switch status to DSR and CTS signaling
			{
				switch_changed = FALSE;

				line_state = 0;
				if ( Switch1State ) line_state |= CDC_DSR;
//				if ( Switch2State ) line_state |= CDC_CTS;		// CTS is not supported in generic CDC
				Update_Line_State( line_state );
			}

			while (TXReady && RXReady)			// loop back TX to RX
			{
				dt = COMGetByte();
				COMPutByte( dt );
			}

			Led1 = uart_DTR;					// output line status
			Led2 = uart_RTS;
		}

	}
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Sysclk_Init
//-----------------------------------------------------------------------------
//
// Initialize the system clock and USB clock
//
//-----------------------------------------------------------------------------

#if defined KEIL
#include <intrins.h>
#endif

static void Sysclk_Init(void)
{
	CLKSEL  =  0x00;					// Set SYSCLK to 12 / 8 MHz
	OSCICN &= ~0x03;
	CLKMUL	=  0x00;					// Select internal oscillator as
										// input to clock multiplier
	CLKMUL |=  0x80;					// Enable clock multiplier
										// delay about 5 us (8 clock)
#if defined KEIL
	_nop_();	_nop_();	_nop_();	_nop_();
	_nop_();	_nop_();	_nop_();	_nop_();
#endif

#if defined SDCC
	_asm
		DIV AB
	_endasm;
#endif

	CLKMUL |=  0xC0;					// Initialize the clock multiplier
	while(!(CLKMUL & 0x20));			// Wait for multiplier to lock

#if defined C8051F320_H
	CLKSEL	= USB_4X_CLOCK | SYS_4X_DIV_2;	// Select system clock and USB clock
#endif // C8051F320_H

#if defined C8051F340_H
	FLSCL  |= 0x10;						// set FLRT for 48MHz SYSCLK
	CLKSEL	= USB_4X_CLOCK | SYS_4X;	// Select system clock and USB clock
#endif // C8051F340_H

}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// This function configures the crossbar and GPIO ports.
//
// F320DB
//  P1.7		analog					Potentiometer
//  P2.2		digital	push-pull		LED
//  P2.3		digital	push-pull		LED
//
// F340DB
//  P2.2		digital push-pull		LED
//  P2.3		digital push-pull		LED
//  P2.5		analog					Potentiometer
//-----------------------------------------------------------------------------
static void Port_Init(void)
{

#if defined C8051F320_H
	P1MDIN	 = 0x7F;					// Port 1 pin 7 set as analog input
	P0MDOUT |= 0x0F;					// Port 0 pins 0-3 set push-pull
	P1MDOUT |= 0x0F;					// Port 1 pins 0-3 set push-pull
	P2MDOUT |= 0x0C;					// P2.2 and P2.3 set to push-pull
	P1SKIP	 = 0x80;					// Port 1 pin 7 skipped by crossbar
	XBR0	 = 0x00;
	XBR1	 = 0x40;					// Enable Crossbar
#endif // C8051F320_H

#if defined C8051F340_H
	P2MDIN   = ~(0x20);					// Port 2 pin 5 set as analog input
	P0MDOUT |= 0x0F;					// Port 0 pins 0-3 set high impedence
	P1MDOUT |= 0x0F;					// Port 1 pins 0-3 set high impedence
	P2MDOUT |= 0x0C;					// Port 2 pins 0,1 set high empedence
	P2SKIP   = 0x20;					// Port 2 pin 5 skipped by crossbar
	XBR0     = 0x00;
	XBR1     = 0x40;					// Enable Crossbar
#endif // C8051F340_H

}

//-----------------------------------------------------------------------------
// Usb_Suspend
//-----------------------------------------------------------------------------
//
// Enter suspend mode after suspend signalling is present on the bus
//		- called from USB ISR
//
//-----------------------------------------------------------------------------

//---------------------------
// SDCC suport
//---------------------------
#if defined SDCC
#pragma save
#pragma nooverlay
#endif // SDCC

#ifdef ENABLE_SUSPEND_RESUME

void Usb_Suspend(void)
{			
	// Put the device in a low power configuration
	P0MDIN	= 0x00;						// Port 0 configured as analog input
	P1MDIN	= 0x00;						// Port 1 configured as analog input
	P2MDIN	= 0x00;						// Port 2 configured as analog input
	P3MDIN	= 0x00;						// Port 3 configured as analog input

//	ADC0CN &= ~0x80;					// Disable ADC0
//	REF0CN	= 0x00;						// Disable voltage reference

	OSCICN |= 0x20;						// Put oscillator to suspend

	// When the device receives a non-idle USB event, it will resume execution
	// on the instruction that follows OSCICN |= 0x20.		

	// Re-enable everything that was disabled when going into Suspend
#if defined C8051F320_H
	P0MDIN	= 0xFF;						// Port 0 configured as diital input
	P1MDIN	= 0x7F;						// Port 1 pin 7 set as analog input
	P2MDIN	= 0xFF;						// Port 2 configured as diital input
	P3MDIN	= 0xFF;						// Port 3 configured as diital input
#endif // C8051F320_H

#if defined C8051F340_H
	P0MDIN	= 0xFF;						// Port 0 configured as diital input
	P1MDIN	= 0xFF;						// Port 1 configured as diital input
	P2MDIN  = ~(0x20);					// Port 2 pin 5 set as analog input
	P3MDIN	= 0xFF;						// Port 3 configured as diital input
#endif // C8051F340_H


//	REF0CN	= 0x0E;						// Enable voltage reference VREF
//	ADC0CN |= 0x80;						// Re-enable ADC

}

#endif	// ENABLE_SUSPEND_RESUME

//---------------------------
// SDCC suport
//---------------------------
#if defined SDCC
#pragma restore
#endif // SDCC

//-----------------------------------------------------------------------------
// Usb_Resume
//-----------------------------------------------------------------------------
//
// Resume normal USB operation
//		- called from USB ISR
//
//-----------------------------------------------------------------------------

//---------------------------
// SDCC suport
//---------------------------
#if defined SDCC
#pragma save
#pragma nooverlay
#endif // SDCC

#ifdef ENABLE_SUSPEND_RESUME

// In this implementation, suspend/resume is supported by the oscillator suspend (OSCICN.5)
// Then, the resume process is also coded in Usb_Suspend(), just after "OSCICN |= 0x20"
/*
void Usb_Resume(void)
{
}
*/
#endif	// ENABLE_SUSPEND_RESUME

//---------------------------
// SDCC suport
//---------------------------
#if defined SDCC
#pragma restore
#endif // SDCC

//-----------------------------------------------------------------------------
// Timer_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters	: None
// 
// Timer 2 reload, used to check if switch pressed on overflow and
// used for ADC continuous conversion
//-----------------------------------------------------------------------------

void Timer_Init(void)
{
	TMR2CN	 = 0x00;					// Stop Timer2; Clear TF2;

	CKCON	&= ~0xF0;					// Timer2 clocked based on T2XCLK;
	TMR2RL	 = 0;						// Initialize reload value
	TMR2	 = 0xffff;					// Set to reload immediately

	TR2		 = 1;						// Start Timer2
}

//-----------------------------------------------------------------------------
// Timer2_ISR
//-----------------------------------------------------------------------------
//
// Called when timer 2 overflows, check to see if switch is pressed,
// then watch for release.
//
//-----------------------------------------------------------------------------

void Timer2_ISR(void) interrupt 5
{
	TF2H = 0;							// Clear Timer2 interrupt flag

	if ( !Sw1 )							// Check for switch #1 pressed
	{
		if ( !Toggle1 )					// Toggle is used to debounce switch
		{								// so that one press and release will
			Switch1State = !Switch1State; // toggle the state of the switch sent
			Toggle1 = TRUE;				// to the host
			switch_changed = TRUE;
		}
	}
	else Toggle1 = FALSE;				// Reset toggle variable

	if ( !Sw2 )							// Same as above, but Switch2
	{
		if ( !Toggle2 )
		{
			Switch2State = !Switch2State;
			Toggle2 = TRUE;
			switch_changed = TRUE;
		}
	}
	else Toggle2 = FALSE;
}


//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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