?? ctrlrequest.c
字號:
/*
**********************************************************************************************
* Project: TK7821
* File: CtrlRequest.c
* Contents:
*
*
* $Date: 02/25/05 Jason v0.1
* 05/12/05 Mingo v0.2 www.fameg.com
*
* Copyright (c) 2005 Fameg, Inc. All rights reserved
***********************************************************************************************
*/
#include <reg51.h>
#include <stdio.h>
#include <string.h>
#include "sotatype.h"
#include "usbdisk.h"
#include "device.h"
#include "CtrlRequest.h"
#include "ScsiCmd.h"
void InitBulkPipe();
/*************************************************
Global Variables
*************************************************/
BYTE xdata UsbBuf[USB_BUFFER_SIZE];
xdata PSOTA_USB_REQUEST pSotaUsbRequest;
xdata BYTE CtrlPktSize;
/*************************************************
Local Variables
*************************************************/
static xdata SOTA_USB_REQUEST SotaUsbRequest;
static xdata BYTE UsbAddr = 0;
static xdata BYTE TestModeParam;
/* H/W b1 only support ep0~2 so we add this variable to pass chapter9 */
static bit EP3Halt = 0;
//----------------------------------------------------------------------------
// EP Index to Register Offset
// Note: Return value 0xff = Invalid EP Index
// 0x00 = EP0
//----------------------------------------------------------------------------
BYTE CtrlEPIndex2RegOffset(BYTE Index)
{
BYTE Offset = 0xff;
if ( (Index == 0) || (Index==0x80) )
Offset = 0;
switch(Index)
{
case EP1IN_NUMBER:
Offset = EP1_TXCSR;
break;
case EP2OUT_NUMBER:
Offset = EP2_RXCSR;
break;
default:
break;
}
return Offset;
}
//----------------------------------------------------------------------------
// Clear Halt Feature
//----------------------------------------------------------------------------
void CtrlClearHaltFeature()
{
// EP0
pSotaUsbRequest->HaltStatus = false;
// EP1
ClearRegBit(USB_BASE + EP1_TXCSR, ~EN_TX1_STL);
// EP2
ClearRegBit(USB_BASE + EP2_RXCSR, BulkStallMask);
}
//----------------------------------------------------------------------------
// Prepare status report data
// Note: Unexpected condition, return false
//----------------------------------------------------------------------------
bool CtrlStatusReport(BYTE Recipient, BYTE Index, PBYTE Data)
{
bit Rc = true;
Data[1] = 0; // Reserved
switch(Recipient)
{
case 0x80: // Device
case 0x81: // Interface
Data[0] = 0;
break;
case 0x82: // Endpoint
{
BYTE Offset = CtrlEPIndex2RegOffset(Index);
Data[0] = 0;
if (Offset != 0xff)
{
if (Offset)
{
if (CSRRead(USB_BASE + Offset) & 0x02)
Data[0] = 0x01;
}
else
{
if (pSotaUsbRequest->HaltStatus)
Data[0] = 0x01;
}
}
break;
}
default:
Rc = false;
break;
}
return Rc;
}
//----------------------------------------------------------------------------
// Get Status Request
//----------------------------------------------------------------------------
void CtrlReqGetStatus()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
pSotaUsbRequest->LoadInDataOk = true;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
BYTE i;
BYTE Len = (BYTE)(pReq->wLength);
BYTE Data[2];
BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];
BYTE Recipient = pReq->bmRequestType;
if (pSotaUsbRequest->LoadInDataOk)
{
if (Len > 2)
Len = 2;
if (!CtrlStatusReport(Recipient, Index, Data))
Len = 0;
CSRWrite(USB_BASE + EP0_TXCNT, Len);
for (i = 0; i < Len; i++)
CSRWrite(USB_BASE + EP0_TXDATA, Data[i]);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
pSotaUsbRequest->LoadInDataOk = false;
}
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
break;
}
case IN_OK_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
break;
case OUT_TOKEN:
default:
// Ctrl Read End
pSotaUsbRequest->InProgress = false;
break;
}
}
//--------------------------------------------------------------------
// Clear Feature Request
//--------------------------------------------------------------------
static bit FeatureCleared = 0;
void ClrFeatureEP()
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
BYTE RegValue;
BYTE wValue = (BYTE)ConvertEndian16(pReq->wValue);
bit ReqAccept = true;
bit ClrEP0 = false;
bit ClrEP1 = false;
bit ClrEP2 = false;
if(wValue == ENDPOINT_HALT)
{
if((pReq->bmRequestType == 0x00)|| // Recipient = Device
(pReq->bmRequestType == 0x01) ) // Recipient = Interface
{
RegValue = CSRRead(USB_BASE + EP0_RXCSR);
if(RegValue & EN_RX0_STL)
ClrEP0 = true;
RegValue = CSRRead(USB_BASE + EP0_TXCSR);
if(RegValue & EN_TX0_STL)
ClrEP0 = true;
RegValue = CSRRead(USB_BASE + EP1_TXCSR);
if(RegValue & EN_TX1_STL)
ClrEP1 = true;
RegValue = CSRRead(USB_BASE + EP2_RXCSR);
if(RegValue & EN_RX2_STL)
ClrEP2 = true;
}
else if(pReq->bmRequestType == 0x02) // Recipient = EndPoint
{
BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];
if((Index == 0)||(Index == 0x80)) // Clear EP0
ClrEP0 = true;
else if(Index == EP1IN_NUMBER)
ClrEP1 = true;
else if(Index == EP2OUT_NUMBER)
ClrEP2 = true;
else
ReqAccept = false;
}
else
ReqAccept = false;
// Clear Endpoint Toggle Feature
RegValue = CSRRead(USB_BASE + EPCTL);
if(ClrEP0) RegValue |= CLR_EP0_TOG;
if(ClrEP1) RegValue |= CLR_EP1_TOG;
if(ClrEP2) RegValue |= CLR_EP2_TOG;
CSRWrite(USB_BASE + EPCTL, RegValue);
if(ClrEP0)
{
pSotaUsbRequest->HaltStatus = false;
RegValue = CSRRead(USB_BASE + EP0_RXCSR);
RegValue &= ~EN_RX0_STL;
CSRWrite(USB_BASE + EP0_RXCSR, RegValue);
RegValue = CSRRead(USB_BASE + EP0_TXCSR);
RegValue &= ~EN_TX0_STL;
CSRWrite(USB_BASE + EP0_TXCSR, RegValue);
}
if(ClrEP1 | ClrEP2)
{
RegValue = CSRRead(USB_BASE + EP1_TXCSR);
RegValue &= ~EN_TX1_STL;
CSRWrite(USB_BASE + EP1_TXCSR, RegValue);
RegValue = CSRRead(USB_BASE + EP2_RXCSR);
RegValue &= ~(EN_RX2_STL | EN_RX2);
CSRWrite(USB_BASE + EP2_RXCSR, RegValue);
}
FeatureCleared = 1;
}
if(ReqAccept)
{
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
}
else
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
}
void BulkReportHandle();
void CtrlReqClearFeature()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
FeatureCleared = 0;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
ClrFeatureEP();
break;
case OUT_TOKEN:
case IN_OK_TOKEN:
default:
pSotaUsbRequest->InProgress = false;
if(FeatureCleared)
{
if(ScsiCmdSTALLed)
{
BulkReportHandle();
ScsiCmdSTALLed = false;
}
}
break;
}
}
//----------------------------------------------------------------------------
// Set USB Test Mode.
//----------------------------------------------------------------------------
void CtrlSetTestMode(BYTE TestItem)
{
BYTE TestModeReg;
if ((((UINT32)HwId() << 16) | HwVersion()) >= 0x60340100)
TestModeReg = USB_TEST_MODE1;
else
TestModeReg = USB_TEST_MODE0;
switch (TestItem)
{
case TEST_J:
CSRWrite(USB_BASE + TestModeReg, SET_TM_J);
break;
case TEST_K:
CSRWrite(USB_BASE + TestModeReg, SET_TM_K);
break;
case TEST_SE0_NAK:
CSRWrite(USB_BASE + TestModeReg, SET_TM_SE0_NAK);
break;
case TEST_PACKET:
while (true)
{
BYTE i;
CSRWrite(USB_BASE + TestModeReg, SET_TM_PKT);
for (i = 0; i < 120; i++); // Delay about 111us under 11MHz
CSRWrite(USB_BASE + TestModeReg, 0);
}
break;
case TEST_FORCE_ENABLE:
// Not Support.
default:
TestModeParam = NO_TEST_PARAM;
break;
}
}
//----------------------------------------------------------------------------
// Check USB Test Mode Parameters.
//----------------------------------------------------------------------------
bool CtrlChkTestMode(PUSB_REQUEST pReq, PBYTE Param)
{
bit Rc = false;
if (pReq->bmRequestType == 0)
{
if (((TDataCast *)&(pReq->wIndex))->ucByte[0] == 0)
{
if (pReq->wLength == 0)
{
*Param = (BYTE)(pReq->wIndex);
Rc = true;
}
}
}
return Rc;
}
//----------------------------------------------------------------------------
// Set Feature Request,Only Support EP0 ~ EP3.
//----------------------------------------------------------------------------
void CtrlReqSetFeature()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
TestModeParam = NO_TEST_PARAM;
break;
case IN_TOKEN:
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
bit ReqAccept = false;
BYTE Value = (BYTE)ConvertEndian16(pReq->wValue);
if (ENDPOINT_HALT == Value)
{
if (pReq->bmRequestType == 0x02)
{
BYTE Index = ((TDataCast *)&(pReq->wIndex))->ucByte[0];
BYTE Offset = CtrlEPIndex2RegOffset(Index);
if (Offset == 0xff)
ReqAccept = false;
else
{
ReqAccept = true;
if (Offset)
CSRWrite(USB_BASE + Offset, 0x02);
else // Set EP0
pSotaUsbRequest->HaltStatus = true;
}
}
}
if (TEST_MODE == Value)
ReqAccept = CtrlChkTestMode(pReq, &TestModeParam);
if (DEVICE_REMOTE_WAKEUP == Value)
{
// Not Support Yet!
ReqAccept = true;
}
if (ReqAccept)
{
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
}
else
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
break;
}
case IN_OK_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -