📄 usb_isr.c
字号:
/*
Copyright 2003 Cygnal Integrated Products, Inc. File: usb_isr.c
Author: JS
Created: JAN 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(): Bulk or Interrupt IN interrupt
handler.
- USBReset (): USB Reset event handler.
******************************************/
#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;
extern BYTE OUT_PACKET[];
extern BYTE IN_PACKET[];
//---------------------------// 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(); }
// Check for Endpoint0 interrupt if (bInInt & rbEP0)
{
// Call Endpoint0 handler
Endpoint0 ();
} // Endpoint1 IN if (bInInt & rbIN1)
{
// Call Endpoint1 IN handler
BulkOrInterruptIn(&gEp1InStatus);
}
// Endpoint2 OUT if (bOutInt & rbOUT2)
{
// Call Endpoint2 OUT handler
BulkOrInterruptOut(&gEp2OutStatus);
}}//---------------------------// 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
}
// 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
}
// 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){
UINT uBytes;
BYTE bTemp = 0;
BYTE bCsrL, bCsrH;
UWRITE_BYTE(INDEX, pEpOutStatus->bEp); // Index to current endpoint
UREAD_BYTE(EOUTCSRL, bCsrL);
UREAD_BYTE(EOUTCSRH, bCsrH);
// Make sure this endpoint is not halted
if (pEpOutStatus->bEpState != EP_HALTED)
{
// Handle STALL condition sent
if (bCsrL & rbOutSTSTL)
{
// Clear Send Stall, Sent Stall, and data toggle
UWRITE_BYTE(EOUTCSRL, rbOutCLRDT);
}
// Read received packet(s)
// If double-buffering is enabled, multiple packets may be ready
while(bCsrL & rbOutOPRDY)
{
// Get packet length
UREAD_BYTE(EOUTCNTL, bTemp); // Low byte
uBytes = (UINT)bTemp & 0x00FF;
UREAD_BYTE(EOUTCNTH, bTemp); // High byte
uBytes |= (UINT)bTemp << 8;
if (uBytes == 8)
{
// Read FIFO
FIFORead(pEpOutStatus->bEp, uBytes, (BYTE*)&OUT_PACKET);
pEpOutStatus->uNumBytes = uBytes;
}
// If a data packet of anything but 8 bytes is received, ignore
// and flush the FIFO
else
{
UWRITE_BYTE(EOUTCSRL, rbOutFLUSH);
}
// Clear out-packet-ready
UWRITE_BYTE(INDEX, pEpOutStatus->bEp);
UWRITE_BYTE(EOUTCSRL, 0);
// Read updated status register
UREAD_BYTE(EOUTCSRL, bCsrL);
}
}
}
//---------------------------// Endpoint Bulk or Interrupt IN Handler//---------------------------void BulkOrInterruptIn (PEP_STATUS pEpInStatus){
BYTE bCsrL, bCsrH;
UWRITE_BYTE(INDEX, pEpInStatus->bEp); // Index to current endpoint
UREAD_BYTE(EINCSRL, bCsrL);
UREAD_BYTE(EINCSRH, bCsrH);
// Make sure this endpoint is not halted
if (pEpInStatus->bEpState != EP_HALTED)
{
// Handle STALL condition sent
if (bCsrL & rbInSTSTL)
{
UWRITE_BYTE(EINCSRL, rbInCLRDT); // Clear Send Stall and Sent Stall,
// and clear data toggle
}
// If a FIFO slot is open, write a new packet to the IN FIFO
while (!(bCsrL & rbInINPRDY))
{
pEpInStatus->uNumBytes = 8;
pEpInStatus->pData = (BYTE*)&IN_PACKET;
// Write <uNumBytes> bytes to the <bEp> FIFO
FIFOWrite(pEpInStatus->bEp, pEpInStatus->uNumBytes,
(BYTE*)pEpInStatus->pData);
// Set Packet Ready bit (INPRDY)
UWRITE_BYTE(EINCSRL, rbInINPRDY);
// Check updated endopint status
UREAD_BYTE(EINCSRL, bCsrL);
}
}
}
//---------------------------
// USBReset
//---------------------------
// - Initialize the global Device Status structure (all zeros)
// - Resets all endpoints
//void USBReset (){
BYTE i, bPower = 0;
BYTE * pDevStatus; // Reset device status structure to all zeros (undefined)
pDevStatus = (BYTE *)&gDeviceStatus;
for (i=0;i<sizeof(DEVICE_STATUS);i++)
{
*pDevStatus++ = 0x00;
}
// Set device state to default
gDeviceStatus.bDevState = DEV_DEFAULT;
// REMOTE_WAKEUP_SUPPORT and SELF_POWERED_SUPPORT
// defined in file "usb_desc.h"
gDeviceStatus.bRemoteWakeupSupport = REMOTE_WAKEUP_SUPPORT;
gDeviceStatus.bSelfPoweredStatus = SELF_POWERED_SUPPORT; // Reset all endpoints
// Reset Endpoint0
gEp0Status.bEpState = EP_IDLE; // Reset Endpoint0 state
gEp0Status.bEp = 0; // Set endpoint number
gEp0Status.uMaxP = EP0_MAXP; // Set maximum packet size
// Reset Endpoint1 IN
gEp1InStatus.bEpState = EP_HALTED; // Reset state
gEp1InStatus.uNumBytes = 0; // Reset byte counter
// Reset Endpoint2 OUT
gEp2OutStatus.bEpState = EP_HALTED; // Reset state
gEp2OutStatus.uNumBytes = 0; // Reset byte counter
// Get Suspend enable/disable status. If enabled, prepare temporary
// variable bPower.
if (SUSPEND_ENABLE)
{
bPower = 0x01; // Set bit0 (Suspend Enable)
}
// Get ISO Update enable/disable status. If enabled, prepare temporary
// variable bPower.
if (ISO_UPDATE_ENABLE)
{
bPower |= 0x80; // Set bit7 (ISO Update Enable)
}
UWRITE_BYTE(POWER, bPower);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -