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

📄 usb_isr.c

📁 CyPress的C8051F32X系列底层驱动(C语言)及上位机demo(vc环境)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   Copyright 2005 Silicon Laboratories Inc.
   File:    usb_isr.c
   Author:  JS & CS original, modified by JM
   Created: OCT 03

   Target Device: C8051F320

   Source file for USB firmware. Includes the following routines:

   - USB_ISR(): Top-level USB interrupt handler. All USB handler
      routines are called from here.
   - Endpoint0(): Endpoint0 interrupt handler.
   - BulkOrInterruptOut(): Bulk or Interrupt OUT interrupt
      handler.
   - BulkOrInterruptIn(): Places DataToWrite on the IN FIFO.
   - USBReset (): USB Reset event handler.
   - State_Machine(): USB state machine
   - Receive_Setup(): Determine whether a read or write request
      been received and initializes variables accordingly.
   - Receive_File(): Receives and saves data
   - Page_Erase(): Erases a page of FLASH
   - Page_Write(): Writes to a page of FLASH

******************************************/

#include "c8051F320.h"
#include "usb_regs.h"
#include "usb_structs.h"
#include "usb_main.h"
#include "usb_desc.h"
#include "usb_config.h"
#include "usb_request.h"

extern DEVICE_STATUS gDeviceStatus;
extern EP0_COMMAND gEp0Command;
extern EP_STATUS gEp0Status;
extern EP_STATUS gEp1InStatus;
extern EP_STATUS gEp2OutStatus;

//	Constants Definitions
#define	NUM_STG_PAGES	20	//	Total number of flash pages to be used for file storage
#define MAX_BLOCK_SIZE	64	//	Use the maximum block size of 64 bytes
#define	FLASH_PAGE_SIZE	512	//	Size of each flash page
#define	BLOCKS_PR_PAGE	FLASH_PAGE_SIZE/MAX_BLOCK_SIZE
#define MAX_NUM_BLOCKS	BLOCKS_PR_PAGE*NUM_STG_PAGES

// UINT type definition
#ifndef _UINT_DEF_
#define _UINT_DEF_
typedef unsigned int UINT;
#endif  /* _UINT_DEF_ */

// BYTE type definition
#ifndef _BYTE_DEF_
#define _BYTE_DEF_
typedef unsigned char BYTE;
#endif   /* _BYTE_DEF_ */

//	Message Types
#define	READ_MSG	0x00	//	Message types for communication with host
#define	WRITE_MSG	0x01
#define	SIZE_MSG	0x02

//	Machine States
#define	ST_WAIT_DEV	0x01	//	Wait for application to open a device instance
#define	ST_IDLE_DEV	0x02	//	Device is open, wait for Setup Message from host
#define	ST_RX_SETUP	0x04	//	Received Setup Message, decode and wait for data
#define	ST_RX_FILE	0x08	//	Receive file data from host
#define	ST_TX_FILE	0x10	//	Transmit file data to host
#define	ST_TX_ACK	0x20	//	Transmit ACK 0xFF back to host after every 8 packets
#define	ST_ERROR	0x80	//	Error state


typedef struct {			//	Structure definition of a block of data
	BYTE Piece[MAX_BLOCK_SIZE];
}	BLOCK;

typedef struct {			//	Structure definition of a flash memory page
	BYTE FlashPage[FLASH_PAGE_SIZE];
}	PAGE;

xdata	BLOCK	TempStorage[BLOCKS_PR_PAGE];	//	Temporary storage of between flash writes

code	BYTE	Pg0	_at_	0x1400;
code	BYTE	Pg1	_at_	0x1600;
code	BYTE	Pg2	_at_	0x1800;
code	BYTE	Pg3	_at_	0x1A00;
code	BYTE	Pg4	_at_	0x1C00;
code	BYTE	Pg5	_at_	0x1E00;
code	BYTE	Pg6	_at_	0x2000;
code	BYTE	Pg7	_at_	0x2200;
code	BYTE	Pg8	_at_	0x2400;
code	BYTE	Pg9	_at_	0x2600;

code	BYTE	Pg10	_at_	0x2800;
code	BYTE	Pg11	_at_	0x2A00;
code	BYTE	Pg12	_at_	0x2C00;
code	BYTE	Pg13	_at_	0x2E00;
code	BYTE	Pg14	_at_	0x3000;
code	BYTE	Pg15	_at_	0x3200;
code	BYTE	Pg16	_at_	0x3400;
code	BYTE	Pg17	_at_	0x3600;
code	BYTE	Pg18	_at_	0x3800;
code	BYTE	Pg19	_at_	0x3A00;

idata	BYTE*	PageIndices[20]	=	{&Pg0,	&Pg1,	&Pg2,	&Pg3,	&Pg4,	&Pg5,	&Pg6,	&Pg7,	&Pg8,	&Pg9
									,&Pg10,	&Pg11,	&Pg12,	&Pg13,	&Pg14,	&Pg15,	&Pg16,	&Pg17,	&Pg18,	&Pg19};
data	UINT	BytesToWrite;	//  Total number of bytes to write to the host
data	UINT	BytesToRead;	//	Total number of bytes to read from host
data	BYTE	Buffer[3];		//	Buffer for Setup messages
data	BYTE	NumBlocks;		//	Number of Blocks for this transfer
data	BYTE	M_State;		//	Current Machine State
data	BYTE	BlockIndex;		//	Index of Current Block in Page
data	BYTE	PageIndex;		//	Index of Current Page in File
data	BYTE	BlocksRead;		//	Total Number of Blocks Read
data	BYTE	BlocksWrote;	//	Total Number of Blocks Written
data	BYTE*	ReadIndex;

//code	const	BYTE	Serial1[0x0A]	=	{0x0A,0x03,'A',0,'B',0,'C',0,'D',0};
	//	Serial Number Defintion

code	BYTE	LengthFile[3]	_at_	0x1200;
	//	{Length(Low Byte), Length(High Byte), Number of Blocks}

sbit Led1 = P2^2; // LED='1' means ON
sbit Led2 = P2^3; // These blink to indicate data transmission

void	State_Machine(void);		//	Determine new state and act on current state
void	Receive_Setup(void);		//	Receive and decode setup packet from host
void	Receive_File(void);			//	Receive file data from host

//---------------------------
//  USB ISR
//---------------------------
//
// This is the top level USB ISR. All endpoint interrupt/request
// handlers are called from this function.
//
// Handler routines for any configured interrupts should be
// added in the appropriate endpoint handler call slots.
//
void USB_ISR () interrupt 8
{
   BYTE bCommonInt, bInInt, bOutInt;

   // Read interrupt registers
   UREAD_BYTE(CMINT, bCommonInt);
   UREAD_BYTE(IN1INT, bInInt);
   UREAD_BYTE(OUT1INT, bOutInt);

   // Check for reset interrupt
   if (bCommonInt & rbRSTINT)
   {
      // Call reset handler
     USBReset();
	  M_State = ST_WAIT_DEV;
   }

   // Check for Endpoint0 interrupt
   if (bInInt & rbEP0)
   {
      // Call Endpoint0 handler
      Endpoint0();
   }

   // Endpoint1 IN
   if (bInInt & rbIN1)
   {
   		 if (M_State == ST_RX_FILE)                 // Ack Transmit complete, go to RX state
         {
           M_State = (ST_TX_ACK);
         }
         if (M_State == ST_TX_FILE)                 // File block transmit complete, go to TX state
         {
		   M_State = (BlocksWrote == NumBlocks) ? ST_IDLE_DEV : ST_TX_FILE;      // Go to Idle when done
         }
   }

   // Endpoint2 OUT
   if (bOutInt & rbOUT2)
   {
      // Call Endpoint2 OUT handler
      BulkOrInterruptOut(&gEp2OutStatus);
      
	  M_State = (M_State == ST_IDLE_DEV) ? ST_RX_SETUP : ST_RX_FILE;
   }
   
   State_Machine();
}

//---------------------------
//  Endpoint0 Handler
//---------------------------
void Endpoint0 ()
{
   BYTE bTemp = 0;
   BYTE bCsr1, uTxBytes;

   UWRITE_BYTE(INDEX, 0);                 // Target ep0
   UREAD_BYTE(E0CSR, bCsr1);

   // Handle Setup End
   if (bCsr1 & rbSUEND)                   // Check for setup end
   {                                      // Indicate setup end serviced
      UWRITE_BYTE(E0CSR, rbSSUEND);
      gEp0Status.bEpState = EP_IDLE;      // ep0 state to idle
	  M_State = ST_IDLE_DEV;              // ported from usb_file.c
   }

   // Handle sent stall
   if (bCsr1 & rbSTSTL)                   // If last state requested a stall
   {                                      // Clear Sent Stall bit (STSTL)
      UWRITE_BYTE(E0CSR, 0);
      gEp0Status.bEpState = EP_IDLE;      // ep0 state to idle
	  M_State = ST_IDLE_DEV;          // ported from usb_file.c
   }

   // Handle incoming packet
   if (bCsr1 & rbOPRDY)
   {
      // Read the 8-byte command from Endpoint0 FIFO
      FIFORead(0, 8, (BYTE*)&gEp0Command);

      // Byte-swap the wIndex field
      bTemp = gEp0Command.wIndex.c[1];
      gEp0Command.wIndex.c[1] = gEp0Command.wIndex.c[0];
      gEp0Command.wIndex.c[0] = bTemp;

      // Byte-swap the wValue field
      bTemp = gEp0Command.wValue.c[1];
      gEp0Command.wValue.c[1] = gEp0Command.wValue.c[0];
      gEp0Command.wValue.c[0] = bTemp;

      // Byte-swap the wLength field
      bTemp = gEp0Command.wLength.c[1];
      gEp0Command.wLength.c[1] = gEp0Command.wLength.c[0];
      gEp0Command.wLength.c[0] = bTemp;

      // Decode received command
      switch (gEp0Command.bmRequestType & CMD_MASK_COMMON)
      {
         case  CMD_STD_DEV_OUT:           // Standard device requests
            // Decode standard OUT request
            switch (gEp0Command.bRequest)
            {
               case SET_ADDRESS:
                  SetAddressRequest();
                  break;
               case SET_FEATURE:
                  SetFeatureRequest();
                  break;
               case CLEAR_FEATURE:
                  ClearFeatureRequest();
                  break;
               case SET_CONFIGURATION:
                  SetConfigurationRequest();
                  break;
               case SET_INTERFACE:
                  SetInterfaceRequest();
                  break;
               // All other OUT requests not supported
               case SET_DESCRIPTOR:
               default:
                  gEp0Status.bEpState = EP_ERROR;
                  break;
            }
            break;

         // Decode standard IN request
         case CMD_STD_DEV_IN:
            switch (gEp0Command.bRequest)
            {
               case GET_STATUS:
                  GetStatusRequest();
                  break;
               case GET_DESCRIPTOR:
                  GetDescriptorRequest();
                  break;
               case GET_CONFIGURATION:
                  GetConfigurationRequest();
                  break;
               case GET_INTERFACE:
                  GetInterfaceRequest();
                  break;
               // All other IN requests not supported
               case SYNCH_FRAME:
               default:
                  gEp0Status.bEpState = EP_ERROR;
                  break;
            }
            break;
         // All other requests not supported
         default:
            gEp0Status.bEpState = EP_ERROR;
      }

      // Write E0CSR according to the result of the serviced out packet
      bTemp = rbSOPRDY;
      if (gEp0Status.bEpState == EP_ERROR)
      {
         bTemp |= rbSDSTL;                // Error condition handled
                                          // with STALL
         gEp0Status.bEpState = EP_IDLE;   // Reset state to idle
      }

      UWRITE_BYTE(E0CSR, bTemp);
   }

   bTemp = 0;                             // Reset temporary variable

   // If state is transmit, call transmit routine
   if (gEp0Status.bEpState == EP_TX)
   {
      // Check the number of bytes ready for transmit
      // If less than the maximum packet size, packet will
      // not be of the maximum size
      if (gEp0Status.uNumBytes <= EP0_MAXP)
      {
         uTxBytes = gEp0Status.uNumBytes;
         gEp0Status.uNumBytes = 0;        // update byte counter
         bTemp |= rbDATAEND;              // This will be the last
                                          // packet for this transfer
         gEp0Status.bEpState = EP_IDLE;   // Reset endpoint state
      }

      // Otherwise, transmit maximum-length packet
      else
      {
         uTxBytes = EP0_MAXP;
         gEp0Status.uNumBytes -= EP0_MAXP;// update byte counter
      }

      // Load FIFO
      FIFOWrite(0, uTxBytes, (BYTE*)gEp0Status.pData);

      // Update data pointer
      gEp0Status.pData = (BYTE*)gEp0Status.pData + uTxBytes;

      // Update Endpoint0 Control/Status register
      bTemp |= rbINPRDY;                  // Always transmit a packet
                                          // when this routine is called
                                          // (may be zero-length)

      UWRITE_BYTE(E0CSR, bTemp);          // Write to Endpoint0 Control/Status
   }

}

//---------------------------
// Bulk or Interrupt OUT Handler
//---------------------------
void BulkOrInterruptOut(PEP_STATUS pEpOutStatus)

⌨️ 快捷键说明

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