📄 ctrlreq.c
字号:
/*
*********************************************************************************************************
* File: CtrlReq.C
* Contents: Firmware frameworks task dispatcher and device request parser source
*
* $Date: 04/06/06 Kimi v0.1
* $Date: 04/25/06 Kimi v0.2
* $Date: 04/30/06 Kimi v0.3
* $Date: 01/23/07 Kevin v0.4
* Copyright (c) 2006 Fameg, Inc. All rights reserved
*********************************************************************************************************
*/
#include "fs7805.h"
#include "fs7805regs.h"
#include "dscr.h"
#define USB_STALL_EP0() EP0RXCS = EP0RXCS | bmRX0_SESTALL; \
EP0TXCS = EP0TXCS | bmTX0_SESTALL
/*
*********************************************************************************************************
* VARIABLE PROTOTYPES
*********************************************************************************************************
*/
static INT8U SetupData[8], PacketSize;
static INT8U AlternateSetting;
static BOOLEAN HighSpeed;
static INT8U EnterSuspend = 0;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void DR_ClearFeature (void);
static void DR_GetConfiguration (void);
static void DR_GetDescriptor (void);
static void DR_GetInterface (void);
static void DR_GetStatus (void);
static void DR_SetAddress (void);
static void DR_SetConfiguration (void);
static void DR_SetFeature (void);
static void DR_SetInterface (void);
static void GD_DeviceDscr (void);
static void GD_DeviceQualDscr (void);
static void GD_ConfigDscr (void);
static void GD_OtherConfigDscr (void);
static void GD_String (void);
static void SetupCommand (void);
/*
*********************************************************************************************************
* USB_INT_ISR
*
* Description: Interrupt Service Routine
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void USB_INT_ISR (void) interrupt 5
{
if (STINT & bmIDLE3MSINT) // idle interrupt
{
if (EnterSuspend++)
{
USBGCTRL = USBGCTRL | bmSUSPEND;
}
STINT = STINT & (~bmIDLE3MSINT);
}
if (STINT & bmRESUMEIE) // resume interrupt
{
STINT = STINT & (~bmRESUMEIE);
}
if (STINT & bmUSBRSTINT) // reset interrupt
{
while (!(USBGCTRL & bmHS_DETECTED)); // detect USB speed
HighSpeed = USBGCTRL & bmSPEED;
if (HighSpeed) // High speed
{
PacketSize = 64;
}
else // Full speed
{
PacketSize = 64;
}
STINT = STINT & (~bmUSBRSTINT);
}
if ((EPINT & bmRX0INT) && ((EP0RXTKN & bmEP0_SETUP) | (EP0RXTKN & bmEP0_SETUPOW)))
{ // enquire the EP0 RX setup interrupt
EP0RXTKN = EP0RXTKN & (~bmEP0_SETUP) & (~bmEP0_SETUPOW);
SetupCommand(); // Parse command
}
if ((EPINT & bmRX0INT) && (EP0RXTKN & bmEP0_OUT)) // out packet
{
EP0RXTKN = EP0RXTKN & (~bmEP0_OUT);
}
#ifndef ISOCHRONOUS
if ((EPINT & bmEP2INT) && (EP2CS & bmEP_ACK))
{
EPINT = EPINT & (~bmEP2INT); // Clear EP2 interrupt
OutData = TRUE;
}
else
{
EPINT = EPINT & (~bmEP2INT); // Clear EP2 interrupt
}
#else
if (EPINT & bmEP2INT)
{
EPINT = EPINT & (~bmEP2INT); // Clear EP2 interrupt
OutData = TRUE;
}
#endif
#ifndef ISOCHRONOUS
if ((EPINT & bmEP1INT) && (EP1CS & bmEP_ACK))
{
EPINT = EPINT & (~bmEP1INT); // Clear EP1 interrupt
InData = TRUE;
}
else
{
EPINT = EPINT & (~bmEP1INT); // Clear EP1 interrupt
}
#else
if (EPINT & bmEP1INT)
{
EPINT = EPINT & (~bmEP1INT); // Clear EP1 interrupt
InData = TRUE;
}
#endif
}
/*
*********************************************************************************************************
* SETUPCOMMAND
*
* Description: Parse command function
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void SetupCommand (void)
{
INT8U i, count;
count = EP0RXCNT;
if (count == 8)
{
for (i = 0; i < 8; i++) // Receive data
{
SetupData[i] = EP0RXDAT;
}
switch (SetupData[1]) // Parse
{
case SC_GET_STATUS:
DR_GetStatus();
break;
case SC_CLEAR_FEATURE:
DR_ClearFeature();
break;
case SC_SET_FEATURE:
DR_SetFeature();
break;
case SC_SET_ADDRESS:
DR_SetAddress();
break;
case SC_GET_DESCRIPTOR:
DR_GetDescriptor();
break;
case SC_GET_CONFIGURATION:
DR_GetConfiguration();
break;
case SC_SET_CONFIGURATION:
DR_SetConfiguration();
break;
case SC_GET_INTERFACE:
DR_GetInterface();
break;
case SC_SET_INTERFACE:
DR_SetInterface();
break;
default:
USB_STALL_EP0(); // Send STALL
break;
}
}
EP0RXCS = EP0RXCS | bmRX0_EN;
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_GETSTATUS
*
* Description: Get status command
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_GetStatus (void)
{
switch (SetupData[0])
{
case GS_DEVICE:
EP0TXDAT = (Rwuen << 1) | Selfpwr;
break;
case GS_INTERFACE:
EP0TXDAT = 0;
break;
case GS_ENDPOINT:
switch (SetupData[4] & 0x0F)
{
case bmEP1MAP:
EP0TXDAT = (EP1CS & bmEP_SESTALL) >> 1;
break;
case bmEP2MAP:
EP0TXDAT = (EP2CS & bmEP_SESTALL) >> 1;
break;
default:
USB_STALL_EP0(); // Send STALL
return;
}
break;
default:
USB_STALL_EP0(); // Send STALL
return;
}
EP0TXDAT = 0;
EP0TXCNT = 2;
EP0TXCS = EP0TXCS | bmTX0_EN;
while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_CLEARFEATURE
*
* Description: Clear feature
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_ClearFeature (void)
{
switch (SetupData[0])
{
case FT_DEVICE:
if (SetupData[2] == 1)
{
Rwuen = FALSE;
}
else
{
USB_STALL_EP0();
return;
}
break;
case FT_ENDPOINT:
if (SetupData[2] == 0)
{
switch (SetupData[4] & 0x0F)
{
case bmEP1MAP:
EP1CS = EP1CS & (~bmEP_SESTALL) | bmEP_CLRTOG;
break;
case bmEP2MAP:
EP2CS = EP2CS & (~bmEP_SESTALL) | bmEP_CLRTOG;
break;
default:
USB_STALL_EP0();
return;
}
}
else
{
USB_STALL_EP0();
return;
}
break;
default:
USB_STALL_EP0(); // Send STALL
return;
}
EP0TXCNT = 0;
EP0TXCS = EP0TXCS | bmTX0_EN;
while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_SETFEATURE
*
* Description: Set feature
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_SetFeature (void)
{
switch (SetupData[0])
{
case FT_DEVICE:
if (SetupData[2] == 1)
{
Rwuen = TRUE;
}
else if (SetupData[2] == 2)
{
break;
}
else
{
USB_STALL_EP0();
return;
}
break;
case FT_ENDPOINT:
if (SetupData[2] == 0)
{
switch (SetupData[4] & 0x0F)
{
case bmEP1MAP:
EP1CS = EP1CS | bmEP_SESTALL;
break;
case bmEP2MAP:
EP2CS = EP2CS | bmEP_SESTALL;
break;
default:
USB_STALL_EP0();
return;
}
}
else
{
USB_STALL_EP0();
return;
}
break;
default:
USB_STALL_EP0(); // Send STALL
return;
}
EP0TXCNT = 0;
EP0TXCS = EP0TXCS | bmTX0_EN;
while (EP0TXCS & bmTX0_EN);
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_SETADDRESS
*
* Description: Set address
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_SetAddress (void)
{
EP0TXCNT = 0; // Write data length
EP0TXCS = EP0TXCS | bmTX0_EN; // Enable TX
while (EP0TXCS & bmTX0_EN); // Wait complete
if (EP0TXCS & bmTX0_ACK)
{
USBFADDR = SetupData[2]; // Set address
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_GETDESCRIPTOR
*
* Description: Get descriptor
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_GetDescriptor (void)
{
switch (SetupData[3])
{
case GD_DEVICE:
GD_DeviceDscr();
break;
case GD_CONFIGURATION:
if (HighSpeed)
{
GD_ConfigDscr();
}
else
{
GD_OtherConfigDscr();
}
break;
case GD_STRING:
GD_String();
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -