📄 f3xx_usb0_interruptserviceroutine.c
字号:
//-----------------------------------------------------------------------------
// F3xx_USB0_InterruptServiceRoutine.c
//-----------------------------------------------------------------------------
// Copyright 2005 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// Source file for USB firmware. Includes top level ISR with SETUP,
// and Endpoint data handlers. Also includes routine for USB suspend,
// reset, and procedural stall.
//
//
// How To Test: See Readme.txt
//
//
// FID:
// Target: C8051F32x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Silicon Laboratories IDE version 2.6
// Command Line: See Readme.txt
// Project Name: F3xx_MouseExample
//
//
// Release 1.1
// -Minor code comment changes
// -16 NOV 2006
// Release 1.0
// -Initial Revision (PD)
// -07 DEC 2005
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "c8051f3xx.h"
#include "F3xx_USB0_Register.h"
#include "F3xx_USB0_InterruptServiceRoutine.h"
#include "F3xx_USB0_Descriptor.h"
#include "F3xx_USB0_ReportHandler.h"
//-----------------------------------------------------------------------------
// Global Variable Definitions
//-----------------------------------------------------------------------------
unsigned char USB0_STATE; // Holds the current USB State
// def. in F3xx_USB0_InterruptServiceRoutine.h
setup_buffer SETUP; // Buffer for current device
// request information
unsigned int DATASIZE; // Size of data to return
unsigned int DATASENT; // Amount of data sent so far
unsigned char* DATAPTR; // Pointer to data to return
unsigned char EP_STATUS[3] = {EP_IDLE, EP_HALT, EP_HALT};
// Holds the status for each endpoint
//-----------------------------------------------------------------------------
// Local Function Definitions
//-----------------------------------------------------------------------------
void Usb_Resume (void); // resumes USB operation
void Usb_Reset (void); // Called after USB bus reset
void Handle_Control (void); // Handle SETUP packet on EP 0
void Handle_In1 (void); // Handle in packet on EP 1
void Handle_Out1 (void); // Handle out packet on EP 1
void Usb_Suspend (void); // This routine called when
// suspend signalling on bus
void Fifo_Read (unsigned char, unsigned int, unsigned char *);
// Used for multiple byte reads
// of Endpoint fifos
void Fifo_Write_Foreground (unsigned char, unsigned int, unsigned char *);
// Used for multiple byte writes
// of Endpoint fifos in foreground
void Fifo_Write_InterruptServiceRoutine (unsigned char, unsigned int,
unsigned char *);
// Used for multiple byte
// writes of Endpoint fifos
//-----------------------------------------------------------------------------
// 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
{
unsigned char bCommon, bIn, bOut;
POLL_READ_BYTE (CMINT, bCommon); // Read all interrupt registers
POLL_READ_BYTE (IN1INT, bIn); // this read also clears the register
POLL_READ_BYTE (OUT1INT, bOut);
{
if (bCommon & rbRSUINT) // Handle Resume interrupt
{
Usb_Resume ();
}
if (bCommon & rbRSTINT) // Handle Reset interrupt
{
Usb_Reset ();
}
if (bIn & rbEP0) // Handle SETUP packet received
{ // or packet transmitted if Endpoint 0
Handle_Control (); // is in transmit mode
}
if (bIn & rbIN1) // Handle In Packet sent, put new data
{ // on endpoint 1 fifo
Handle_In1 ();
}
if (bOut & rbOUT1) // Handle Out packet received, take
{ // data off endpoint 2 fifo
Handle_Out1 ();
}
if (bCommon & rbSUSINT) // Handle Suspend interrupt
{
Usb_Suspend ();
}
}
}
//-----------------------------------------------------------------------------
// Support Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Usb_Reset
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// - Set state to default
// - Clear Usb Inhibit bit
//
//-----------------------------------------------------------------------------
void Usb_Reset (void)
{
USB0_STATE = DEV_DEFAULT; // Set device state to default
POLL_WRITE_BYTE (POWER, 0x01); // Clear usb inhibit bit to enable USB
// suspend detection
EP_STATUS[0] = EP_IDLE; // Set default Endpoint Status
EP_STATUS[1] = EP_HALT;
EP_STATUS[2] = EP_HALT;
}
//-----------------------------------------------------------------------------
// Usb_Resume
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Resume normal USB operation
//
//-----------------------------------------------------------------------------
void Usb_Resume(void)
{
volatile int k;
k++;
// Add code for resume
}
//-----------------------------------------------------------------------------
// Handle_Control
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// - Decode Incoming SETUP requests
// - Load data packets on fifo while in transmit mode
//
//-----------------------------------------------------------------------------
void Handle_Control (void)
{
unsigned char ControlReg; // Temporary storage for EP control
// register
POLL_WRITE_BYTE (INDEX, 0); // Set Index to Endpoint Zero
POLL_READ_BYTE (E0CSR, ControlReg); // Read control register
if (EP_STATUS[0] == EP_ADDRESS) // Handle Status Phase of Set Address
// command
{
POLL_WRITE_BYTE (FADDR, SETUP.wValue.c[LSB]);
EP_STATUS[0] = EP_IDLE;
}
if (ControlReg & rbSTSTL) // If last packet was a sent stall,
{ // reset STSTL bit and return EP0
// to idle state
POLL_WRITE_BYTE (E0CSR, 0);
EP_STATUS[0] = EP_IDLE;
return;
}
if (ControlReg & rbSUEND) // If last SETUP transaction was
{ // ended prematurely then set
POLL_WRITE_BYTE (E0CSR, rbDATAEND);
// Serviced SETUP End bit and return EP0
POLL_WRITE_BYTE (E0CSR, rbSSUEND);
EP_STATUS[0] = EP_IDLE; // to idle state
}
if (EP_STATUS[0] == EP_IDLE) // If Endpoint 0 is in idle mode
{
if (ControlReg & rbOPRDY) // Make sure that EP 0 has an Out Packet
{ // ready from host although if EP0
// is idle, this should always be the
// case
Fifo_Read (FIFO_EP0, 8, (unsigned char *)&SETUP);
// Get SETUP Packet off of Fifo,
// it is currently Big-Endian
// Compiler Specific - these next three
// statements swap the bytes of the
// SETUP packet words to Big Endian so
// they can be compared to other 16-bit
// values elsewhere properly
SETUP.wValue.i = SETUP.wValue.c[MSB] + 256*SETUP.wValue.c[LSB];
SETUP.wIndex.i = SETUP.wIndex.c[MSB] + 256*SETUP.wIndex.c[LSB];
SETUP.wLength.i = SETUP.wLength.c[MSB] + 256*SETUP.wLength.c[LSB];
// Intercept HID class-specific requests
if( (SETUP.bmRequestType & ~0x80) == DSC_HID) {
switch (SETUP.bRequest) {
case GET_REPORT:
Get_Report ();
break;
case SET_REPORT:
Set_Report ();
break;
case GET_IDLE:
Get_Idle ();
break;
case SET_IDLE:
Set_Idle ();
break;
case GET_PROTOCOL:
Get_Protocol ();
break;
case SET_PROTOCOL:
Set_Protocol ();
break;
default:
Force_Stall (); // Send stall to host if invalid
break; // request
}
} else
switch (SETUP.bRequest) // Call correct subroutine to handle
{ // each kind of standard request
case GET_STATUS:
Get_Status ();
break;
case CLEAR_FEATURE:
Clear_Feature ();
break;
case SET_FEATURE:
Set_Feature ();
break;
case SET_ADDRESS:
Set_Address ();
break;
case GET_DESCRIPTOR:
Get_Descriptor ();
break;
case GET_CONFIGURATION:
Get_Configuration ();
break;
case SET_CONFIGURATION:
Set_Configuration ();
break;
case GET_INTERFACE:
Get_Interface ();
break;
case SET_INTERFACE:
Set_Interface ();
break;
default:
Force_Stall (); // Send stall to host if invalid request
break;
}
}
}
if (EP_STATUS[0] == EP_TX) // See if endpoint should transmit
{
if (!(ControlReg & rbINPRDY) ) // Don't overwrite last packet
{
// Read control register
POLL_READ_BYTE (E0CSR, ControlReg);
// Check to see if SETUP End or Out Packet received, if so do not put
// any new data on FIFO
if ((!(ControlReg & rbSUEND)) || (!(ControlReg & rbOPRDY)))
{
// Add In Packet ready flag to E0CSR bitmask
ControlReg = rbINPRDY;
if (DATASIZE >= EP0_PACKET_SIZE)
{
// Break Data into multiple packets if larger than Max Packet
Fifo_Write_InterruptServiceRoutine (FIFO_EP0, EP0_PACKET_SIZE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -