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

📄 usb_isr.c

📁 C8051F320 USB示波器测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// F32x_USB_ISR.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:            32X000023
// Target:         C8051F32x
// Tool chain:     Keil C51 7.50 / Keil EVAL C51
//                 Silicon Laboratories IDE version 2.6
// Command Line:   See Readme.txt
// Project Name:   F32x_USB_Interrupt
//
//
// Release 1.3
//    -All changes by GP
//    -22 NOV 2005
//    -Changed revision number to match project revision
//    -Modified file to fit new formatting guidelines
//    -Changed file name from USB_ISR.c
//    -Removed extraneous code that was commented out
//    -Added USB Suspend code
//   
// Release 1.0
//    -Initial Revision (DM)
//    -08 NOV 2002
//

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

#include "c8051F320.h"#include "USB_Register.h"
#include "USB_Main.h"
#include "USB_Descriptor.h"

//-----------------------------------------------------------------------------
// Global Externs
//-----------------------------------------------------------------------------

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

unsigned  char * usb_dptr;       /* pointer to first empty location in buffer (Rx) or to the first char to transmit (Tx) */
unsigned  char usb_ep0_dcntT;   /* data count to transmit */
unsigned  char usb_ep0_dcntR;   /* data count to receive */
unsigned  char usb_ep2_dcntT;   /* data count to transmit */
unsigned  char usb_ep2_dcntR;   /* data count to receive */


BYTE USB_State;                        // Holds the current USB State
                                       // def. in F32x_USB_Main.h

setup_buffer Setup;                    // Buffer for current device request

unsigned int DataSize;                 // Size of data to return
unsigned int DataSent;                 // Amount of data sent so far
BYTE* DataPtr;                         // Pointer to data to return

// Holds the status for each endpoint
BYTE Ep_Status[5] = {EP_IDLE, EP_IDLE, EP_IDLE, EP_IDLE, EP_IDLE};


BYTE receive_ep0;
//-----------------------------------------------------------------------------
// 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, 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_Setup();               // is transmit mode
      }      if (bIn & rbIN2)                 // Handle In Packet sent, put new data
      {                                // on endpoint 1 fifo
         Handle_In2();
      }      if (bOut & rbOUT2)               // Handle Out packet received, take data
      {                                // off endpoint 2 fifo
         Handle_Out2();
      }
	  if( bIn & rbIN3)
	  {
	  	 Handle_In3();
	  }
	  if (bOut & rbOUT3)
	  {
	  	 Handle_Out3();
	  }

      if (bCommon & rbSUSINT)          // Handle Suspend interrupt
      {
         Usb_Suspend();
      }
   }
}

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

//-----------------------------------------------------------------------------
// Usb_Reset
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// - Set state to default
// - Clear Usb Inhibit bit
//
//-----------------------------------------------------------------------------

void Usb_Reset(void)
{
   USB_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;
   Ep_Status[3] = EP_HALT;
   Ep_Status[4] = EP_HALT;
   receive_ep0	= 0;

}

//-----------------------------------------------------------------------------
// Handle_Setup
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// - Decode Incoming Setup requests
// - Load data packets on fifo while in transmit mode
//
//-----------------------------------------------------------------------------

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

   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);
      POLL_WRITE_BYTE(E0CSR, rbSSUEND); // Serviced Setup End bit and return EP0
      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

		 if( receive_ep0 == 0)
		 {
	         Fifo_Read(FIFO_EP0, 8, (BYTE *)&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
	
			 if(Setup.bmRequestType == 0xC0 )	//MYBDM命令
			 {
				command_buffer[0] = Setup.bmRequestType;
				command_buffer[1] = Setup.bRequest;
				command_buffer[2] = Setup.wValue.c[MSB];
				command_buffer[3] = Setup.wValue.c[LSB];
				command_buffer[4] = Setup.wIndex.c[MSB];
				command_buffer[5] = Setup.wIndex.c[LSB];
				command_buffer[6] = Setup.wLength.c[MSB];
				command_buffer[7] = Setup.wLength.c[LSB];
			
				
				DataPtr = command_buffer;					// Can have a maximum of 255 strings
				
				if (Ep_Status[0] != EP_STALL)
				{
					POLL_WRITE_BYTE(E0CSR, rbSOPRDY);         // Set Serviced Setup packet, put endpoint in transmit
					Ep_Status[0] = EP_TX;                     // mode and reset Data sent counter
					DataSent = 0;
				}
			 }
			 else if(Setup.bmRequestType == 0x40)
			 {
				command_buffer[0] = Setup.bmRequestType;
				command_buffer[1] = Setup.bRequest;
				command_buffer[2] = Setup.wValue.c[MSB];
				command_buffer[3] = Setup.wValue.c[LSB];
				command_buffer[4] = Setup.wIndex.c[MSB];
				command_buffer[5] = Setup.wIndex.c[LSB];
				command_buffer[6] = Setup.wLength.c[MSB];
				command_buffer[7] = Setup.wLength.c[LSB];
				usb_ep0_dcntR = command_buffer[6];
				if(usb_ep0_dcntR == 0)
				{
			          USB_ep0_rx(); /* the routine will not copy any data, but will launch command execution and status frame transmit */
	                /* this is cleaner as this code is in one place only */
	         	}
				else
				{
					receive_ep0 = 1;

					usb_dptr = command_buffer+6;  /* first 5 bytes stored already starting from position 1 */
					POLL_WRITE_BYTE(E0CSR, rbSOPRDY);         // Set Serviced Setup packet, put endpoint in transmit
	
					DataSent = 0;
			 	}
		        /* data to follow, set-up pointer */  
			 }
			 else
			 {
				 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];
		
		
		         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;
		         }
			 }
		 }
		 else	//	receive_ep0 = 1;
		 {
		 	USB_ep0_rx();
		 }
      }
   }

   if (Ep_Status[0] == EP_TX)          // See if the endpoint has data to transmit to host
   {
      if (!(ControlReg & rbINPRDY))    // Make sure you don't overwrite last packet	Endpoint 0 transmit mode
      {
		 receive_ep0 = 0;
         POLL_READ_BYTE(E0CSR, ControlReg);	   // Read control register
                                       

         if ((!(ControlReg & rbSUEND)) || (!(ControlReg & rbOPRDY)))
                                       // Check to see if Setup End or Out Packet received, if so
                                       // do not put any new data on FIFO
         {
            TempReg = rbINPRDY;        // Add In Packet ready flag to E0CSR bitmask
                                       // Break Data into multiple packets if larger than Max Packet

            if (DataSize >= EP0_PACKET_SIZE)
            {
               Fifo_Write(FIFO_EP0, EP0_PACKET_SIZE, (BYTE *)DataPtr);// Put Data on Fifo
               DataPtr  += EP0_PACKET_SIZE;                           // Advance data pointer
               DataSize -= EP0_PACKET_SIZE;                           // Decrement data size
               DataSent += EP0_PACKET_SIZE;                           // Increment data sent counter
            }
            else                       // If data is less than Max Packet size or zero
            {
               Fifo_Write(FIFO_EP0, DataSize, (BYTE *)DataPtr);       // Put Data on Fifo
               TempReg |= rbDATAEND;                                  // Add Data End bit to bitmask
               Ep_Status[0] = EP_IDLE;                                // Return EP 0 to idle state
            }

            if (DataSent == Setup.wLength.i)
                                        // This case exists when the host requests an even multiple of
                                        // your endpoint zero max packet size, and you need to exit
                                        // transmit mode without sending a zero length packet
            {
               TempReg |= rbDATAEND;    // Add Data End bit to mask

⌨️ 快捷键说明

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