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

📄 usb_isr.c

📁 USB CDC using C8051F320/340, virtual COM port thru usb connection
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// USB_ISR.c
//-----------------------------------------------------------------------------

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

#include "USB_Type.h"
#include "USB_Configuration.h"
#include "USB_Register.h"
#include "USB_Standard_Requests.h"
#include "USB_Class_Requests.h"
#include "USB_CDC_UART.h"
#include "FIFO_RW.h"

//#define ALLOCATE_VARS
#include "USB_ISR.h"

//-----------------------------------------------------------------------------
// configuration conditions
//-----------------------------------------------------------------------------

#if (defined USE_EP1_OUT) && !(defined ENABLE_EP1_OUT_ISO)
	#define USE_EP1_OUT_STATUS
#endif
#if (defined USE_EP2_OUT) && !(defined ENABLE_EP2_OUT_ISO)
	#define USE_EP2_OUT_STATUS
#endif
#if (defined USE_EP3_OUT) && !(defined ENABLE_EP3_OUT_ISO)
	#define USE_EP3_OUT_STATUS
#endif
#if (defined USE_EP1_IN) && !(defined ENABLE_EP1_IN_ISO)
	#define USE_EP1_IN_STATUS
#endif
#if (defined USE_EP2_IN) && !(defined ENABLE_EP2_IN_ISO)
	#define USE_EP2_IN_STATUS
#endif
#if (defined USE_EP3_IN) && !(defined ENABLE_EP3_IN_ISO)
	#define USE_EP3_IN_STATUS
#endif


#ifdef ENABLE_EP1_OUT_INTERRUPT
	#define EP1_OUT_INTEN	rbOUT1E
#else
	#define EP1_OUT_INTEN	0
#endif
#ifdef ENABLE_EP2_OUT_INTERRUPT
	#define EP2_OUT_INTEN	rbOUT2E
#else
	#define EP2_OUT_INTEN	0
#endif
#ifdef ENABLE_EP3_OUT_INTERRUPT
	#define EP3_OUT_INTEN	rbOUT3E
#else
	#define EP3_OUT_INTEN	0
#endif

#ifdef ENABLE_EP1_IN_INTERRUPT
	#define EP1_IN_INTEN	rbIN1E
#else
	#define EP1_IN_INTEN	0
#endif
#ifdef ENABLE_EP2_IN_INTERRUPT
	#define EP2_IN_INTEN	rbIN2E
#else
	#define EP2_IN_INTEN	0
#endif
#ifdef ENABLE_EP3_IN_INTERRUPT
	#define EP3_IN_INTEN	rbIN3E
#else
	#define EP3_IN_INTEN	0
#endif

#ifdef ENABLE_SOF_INTERRUPT
	#define SOF_INTEN		rbSOFE
#else
	#define SOF_INTEN		0
#endif

#ifdef ENABLE_SUSPEND_RESUME
//	#define SUSPEND_RESUME_INTEN		(rbSUSINTE | rbRSUINTE)
	#define SUSPEND_RESUME_INTEN		(rbSUSINTE)
#else
	#define SUSPEND_RESUME_INTEN		0
#endif

#define EP_OUT_INTEN	(EP1_OUT_INTEN | EP2_OUT_INTEN | EP3_OUT_INTEN)
#define EP_IN_INTEN		(EP1_IN_INTEN  | EP2_IN_INTEN  | EP3_IN_INTEN)


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

BYTE          USB_State;			// Hold current usb device state
Tsetup_buffer Setup;				// Buffer for current device request
bit           setup_handled;		// flag that indicates setup stage is handled or not
UINT          DataSize;				// Size of data to return
BYTE*         DataPtr;				// Pointer to data to return

// Holds the status for each endpoint
volatile BYTE Ep_Status0		= EP_IDLE;

#ifdef USE_EP1_OUT_STATUS
	volatile bit Ep_StatusOUT1	= EP_HALT;
#endif
#ifdef USE_EP2_OUT_STATUS
	volatile bit Ep_StatusOUT2	= EP_HALT;
#endif
#ifdef USE_EP3_OUT_STATUS
	volatile bit Ep_StatusOUT3	= EP_HALT;
#endif
#ifdef USE_EP1_IN_STATUS
	volatile bit Ep_StatusIN1	= EP_HALT;
#endif
#ifdef USE_EP2_IN_STATUS
	volatile bit Ep_StatusIN2	= EP_HALT;
#endif
#ifdef USE_EP3_IN_STATUS
	volatile bit Ep_StatusIN3	= EP_HALT;
#endif

// FIFO status of endpoints
volatile bit IN1_FIFO_empty   = TRUE;
volatile bit IN2_FIFO_empty   = TRUE;
volatile bit IN3_FIFO_empty   = TRUE;
volatile bit OUT1_FIFO_loaded = FALSE;
volatile bit OUT2_FIFO_loaded = FALSE;
volatile bit OUT3_FIFO_loaded = FALSE;

// function pointer for the request callback function at the end of control OUT transfer
bit (*USB_request_callback)( void );

//-----------------------------------------------------------------------------
// Static Variables in this file
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Local function prototypes
//-----------------------------------------------------------------------------

static void Handle_Setup(void);					// Handle setup packet on Endpoint 0
static void Usb_Reset(void);					// Called after USB bus reset
static void Handle_SOF(void);

static void Handle_Out1(void);					// Handle out packet on Endpoint 1
static void Handle_Out2(void);					// Handle out packet on Endpoint 2
static void Handle_Out3(void);					// Handle out packet on Endpoint 3
static void Handle_In1(void);					// Handle in packet on Endpoint 1
static void Handle_In2(void);					// Handle in packet on Endpoint 2
static void Handle_In3(void);					// Handle in packet on Endpoint 3

//-----------------------------------------------------------------------------
// Usb0_Init
//-----------------------------------------------------------------------------
//
// - Initialize USB0
// - Enable USB0 interrupts
// - Enable USB0 transceiver
// - Enable USB0 with suspend detection
//-----------------------------------------------------------------------------
void Usb0_Init(void)
{
	POLL_WRITE_BYTE(POWER,	0x08);		// Force Asynchronous USB Reset
										// USB Interrupt enable flags are reset by USB bus reset
	POLL_WRITE_BYTE(IN1IE,	rbEP0E);	// Enable EP 0 interrupt, disable EP1-3 IN interrupt
	POLL_WRITE_BYTE(OUT1IE,	0x00);		// Disable EP 1-3 OUT interrupts

	POLL_WRITE_BYTE(CMIE,	rbRSTINTE | SUSPEND_RESUME_INTEN);	// Enable Reset and Suspend interrupts

	USB0XCN = 0xE0;						// Enable transceiver; select full speed
	POLL_WRITE_BYTE(CLKREC, 0x80);		// Enable clock recovery, single-step mode
										// disabled
#ifdef ENABLE_SUSPEND_RESUME
										// Enable USB0 by clearing the USB Inhibit bit
	POLL_WRITE_BYTE(POWER,	0x01);		// and enable suspend detection
#else
										// Enable USB0 by clearing the USB Inhibit bit
	POLL_WRITE_BYTE(POWER,	0x00);
#endif

}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Usb_ISR
//-----------------------------------------------------------------------------
//
// Called after any USB type interrupt, this handler determines which type
// of interrupt occurred, and calls the specific routine to handle it.
//
//-----------------------------------------------------------------------------

void Usb_ISR(void) interrupt 8			// Top-level USB ISR
{
	BYTE bCommon, bIn;
#if (EP_OUT_INTEN != 0)
	BYTE bOut;
#endif

	POLL_READ_BYTE(CMINT, bCommon);		// Read all interrupt registers
	POLL_READ_BYTE(IN1INT, bIn);		// this read also clears the register

#if (EP_OUT_INTEN != 0)
	POLL_READ_BYTE(OUT1INT, bOut);
#endif
										// Handle Reset interrupt
	if (bCommon & rbRSTINT) {	Usb_Reset();	}
										// Handle EP1-3 interrupt
#ifdef ENABLE_EP1_OUT_INTERRUPT
	if (bOut & rbOUT1) {		Handle_Out1();	}
#endif
#ifdef ENABLE_EP2_OUT_INTERRUPT
//	if (bOut & rbOUT2) {		Handle_Out2();	}
	if (bOut & rbOUT2) {		OUT2_FIFO_loaded = TRUE;	}
#endif
#ifdef ENABLE_EP3_OUT_INTERRUPT
//	if (bOut & rbOUT3) {		Handle_Out3();	}
	if (bOut & rbOUT3) {		OUT3_FIFO_loaded = TRUE;	}
#endif
#ifdef ENABLE_EP1_IN_INTERRUPT
//	if (bIn & rbIN1) {			Handle_In1();	}
	if (bIn & rbIN1) {			IN1_FIFO_empty = TRUE;	}
#endif
#ifdef ENABLE_EP2_IN_INTERRUPT
//	if (bIn & rbIN2) {			Handle_In2();	}
	if (bIn & rbIN2) {			IN2_FIFO_empty = TRUE;	}
#endif
#ifdef ENABLE_EP3_IN_INTERRUPT
//	if (bIn & rbIN3) {			Handle_In3();	}
	if (bIn & rbIN3) {			IN3_FIFO_empty = TRUE;	}
#endif
										// Handle EP0 interrupt
	if (bIn & rbEP0) {			Handle_Setup();	}

#ifdef ENABLE_SUSPEND_RESUME
										// Handle Suspend interrupt
	if (bCommon & rbSUSINT) {	Usb_Suspend();	}
										// Handle Resume interrupt
//	if (bCommon & rbRSUINT) {	Usb_Resume();	}
#endif

										// SOF interrupt
#ifdef ENABLE_SOF_INTERRUPT
//	if (bCommon & rbSOF) {		Handle_SOF();	}
	if (bCommon & rbSOF) {		CDC_Handle_INT_IN();		// Handle Notification endpoint
								CDC_Handle_Bulk_IN_ZLP(); }	// Send ZLP to bulk IN when required
#endif

}

//-----------------------------------------------------------------------------
// Support Routines for ISR
//-----------------------------------------------------------------------------

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

//-----------------------------------------------------------------------------
// Usb_Reset
//-----------------------------------------------------------------------------
//
// - Set state to default
// - Clear Usb Inhibit bit
//
//-----------------------------------------------------------------------------

static void Usb_Reset(void)
{
	POLL_WRITE_BYTE(IN1IE,	rbEP0E | EP_IN_INTEN );		// Enable Ep0 and EP1-3 IN
#if (EP_OUT_INTEN != 0)
	POLL_WRITE_BYTE(OUT1IE, EP_OUT_INTEN );				// Enable EP1-3 OUT
#endif
	POLL_WRITE_BYTE(CMIE,	rbRSTINTE | SUSPEND_RESUME_INTEN | SOF_INTEN);		// Enable Reset, Suspend interrupts

	POLL_WRITE_BYTE(POWER, 0x01);		// Clear usb inhibit bit to enable USB
										// suspend detection

	USB_State = DEV_DEFAULT;			// Set device state to default

	Ep_Status0 = EP_IDLE;				// Set default Endpoint Status

#ifdef USE_EP1_OUT_STATUS
	Ep_StatusOUT1 = EP_HALT;
#endif
#ifdef USE_EP2_OUT_STATUS
	Ep_StatusOUT2 = EP_HALT;
#endif
#ifdef USE_EP3_OUT_STATUS
	Ep_StatusOUT3 = EP_HALT;
#endif
#ifdef USE_EP1_IN_STATUS
	Ep_StatusIN1  = EP_HALT;
#endif
#ifdef USE_EP2_IN_STATUS
	Ep_StatusIN2  = EP_HALT;
#endif
#ifdef USE_EP3_IN_STATUS
	Ep_StatusIN3  = EP_HALT;
#endif

}

//-----------------------------------------------------------------------------
// Handle_Setup
//-----------------------------------------------------------------------------
//
// - Decode Incoming Setup requests
// - Load data packets on fifo while in transmit mode
//
//-----------------------------------------------------------------------------

static bit send_eq_requested = FALSE;	// flag that indicates that the data to send on TX
										// equals to the requested by Setup wLength
										// KEIL doesn't accept static local bit variable
static void Handle_Setup(void)
{
	BYTE ControlReg, TempReg;			// Temporary storage for EP control register

	POLL_WRITE_BYTE(INDEX, 0);			// Set Index to Endpoint Zero
	POLL_READ_BYTE(E0CSR, ControlReg);	// Read control register

⌨️ 快捷键说明

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