📄 ctrlreq.c
字号:
/*
*********************************************************************************************************
* File: CtrlReq.C
* Contents: Firmware frameworks task dispatcher and device request parser source
*
* $Date: 04/06/06 Kimi V0.1
*
* Copyright (c) 2006 Fameg, Inc. All rights reserved
*********************************************************************************************************
*/
#include "include\Include.h"
#include "include\dscr.h"
#define USB_STALL_EP0() EP0RXCS = EP0RXCS | bmRX0_SESTALL; \
EP0TXCS = EP0TXCS | bmTX0_SESTALL
/*
*********************************************************************************************************
* VARIABLE PROTOTYPES
*********************************************************************************************************
*/
static INT8U SetupData[8];
INT8U Configuration=0, AlternateSetting=0;
BOOLEAN HighSpeed; //用来指示是高速(high speed)还是全速(full speed)接口
//1:HIGH SPEED 0:FULL SPEED
//BOOL Rwuen, Selfpwr;
/*
*********************************************************************************************************
* 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 CtrlReqGetMaxLun(void);
static void CtrlReqBulkReset(void);
void SetupCommand (void);
/*
*********************************************************************************************************
* KSOC_INT_ISR
*
* Description: KSOC Interrupt Service Routine
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
//void KSOC_INT_ISR (void) interrupt 6
//{
//}
/*$PAGE*/
/*
*********************************************************************************************************
* SETUPCOMMAND
*
* Description: Parse command function
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void SetupCommand (void)
{
INT8U i = 0, count = 8;
while (count) // Receive data
{
SetupData[i] = EP0RXDAT;
i++;
count--;
}
if((SetupData[0]& 0x60) == 0x00)
{
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;
}
}
else if((SetupData[0]& 0x60) == 0x20)
{
switch (SetupData[1])
{
case BULKONLY_GET_MAX_LUN:
CtrlReqGetMaxLun();
break;
case BULKONLY_RESET:
CtrlReqBulkReset();
break;
}
}
EP0RXCS = EP0RXCS | bmRX0_EN;
}
void CtrlReqGetMaxLun(void)
{
EP0TXCNT = 1;
EP0TXDAT = 0x00;
EP0TXCS = EP0TXCS | bmTX0_EN;
//while (EP0TXCS & bmTX0_EN);
}
void CtrlReqBulkReset(void)
{
BulkState = CBW_GET_COMPLETED;
CmdStatus = COMMAND_PASSED;
EP0TXCNT = 0;
EP0TXCS = EP0TXCS | bmTX0_EN;
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_GETSTATUS
*
* Description: Get status command
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_GetStatus (void)
{
EP0TXCNT = 2;
switch (SetupData[0])
{
case GS_DEVICE:
EP0TXDAT = ((INT8U)Rwuen << 1) | (INT8U)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:
EP0TXDAT = 0;
break;
}
break;
default:
EP0TXDAT = 0;
break;
}
EP0TXDAT = 0;
EP0TXCS = EP0TXCS | bmTX0_EN;
}
/*$PAGE*/
/*
*********************************************************************************************************
* DR_CLEARFEATURE
*
* Description: Clear feature
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void DR_ClearFeature (void)
{ void BulkReportHandle();
switch (SetupData[0])
{
case FT_DEVICE:
if (SetupData[2] == 1)
{
Rwuen = FALSE;
}
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); //EP_TOG位写1清零
break;
}
}
EP0TXCNT = 0;
EP0TXCS = EP0TXCS | bmTX0_EN;//使能EP0发送,给主机回复0字节的数据,完成clear feature的控制传输
while (EP0TXCS & bmTX0_EN); // Wait complete
break;
}
if(ScsiCmdSTALLed) //如果STALL发生,准备回送CSW.Derek 06.09.04
{
BulkReportHandle();
ScsiCmdSTALLed = false;
}
}
/*$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;
}
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;
}
}
break;
}
EP0TXCNT = 0;
EP0TXCS = 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
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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -