?? ctrlrequest.c
字號:
case OUT_TOKEN:
default:
pSotaUsbRequest->InProgress = false;
if (TestModeParam != NO_TEST_PARAM)
{
CtrlSetTestMode(TestModeParam);
// Clear Test Mode until power reset(power cycled).
while(1);
}
break;
}
}
//----------------------------------------------------------------------------
// Set Address Request
// NOTE:
// It is critical on the timing of changing USB address. We must do it
// before next Setup Token (With new address) and after now running
// transaction has been finished.So we end this request without using
// state machine.
//----------------------------------------------------------------------------
void CtrlReqSetAddress()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
UsbAddr = ((TDataCast *)&(pReq->wValue))->ucByte[0];
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
}
case IN_TOKEN:
CSRWrite(USB_BASE + USBADDR, UsbAddr);
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
/*
Before host set address,it would issue usb reset so we
must enable EP1,EP2 again.(These pipe were disable default)
*/
CSRWrite(USB_BASE + EPCTL, EN_EP0 | EN_EP1 | EN_EP2 );
// Clear the Bulk IN/OUT stall bits.
CSRWrite(USB_BASE + EP1_TXCSR, 0x00);
CSRWrite(USB_BASE + EP2_RXCSR, EN_RX2);
pSotaUsbRequest->InProgress = 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:
break;
}
}
static BYTE ConfigSetValue = 1;
//----------------------------------------------------------------------------
// Get Configuration Request
//----------------------------------------------------------------------------
void CtrlReqGetConfiguration()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
pSotaUsbRequest->LoadInDataOk = true;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
if (pSotaUsbRequest->LoadInDataOk)
{
CSRWrite(USB_BASE + EP0_TXCNT, 1);
CSRWrite(USB_BASE + EP0_TXDATA, ConfigSetValue);
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;
}
}
//----------------------------------------------------------------------------
// Set Configuration Request
//----------------------------------------------------------------------------
void CtrlReqSetConfiguration()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
BYTE Value = ((TDataCast *)&(pReq->wValue))->ucByte[0];
ConfigSetValue = Value;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
}
case IN_TOKEN:
CtrlClearHaltFeature();
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
break;
case IN_OK_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
case OUT_TOKEN:
default:
pSotaUsbRequest->InProgress = false;
break;
}
}
//----------------------------------------------------------------------------
// Get Interface Request
//----------------------------------------------------------------------------
void CtrlReqGetInterface()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
pSotaUsbRequest->LoadInDataOk = true;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
if (pSotaUsbRequest->LoadInDataOk)
{
CSRWrite(USB_BASE + EP0_TXCNT, 1);
CSRWrite(USB_BASE + EP0_TXDATA, 0x00);
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;
}
}
//----------------------------------------------------------------------------
// Set Interface Request
//----------------------------------------------------------------------------
void CtrlReqSetInterface()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
// Because we don't support Alternate-IF-Set, we do nothing here.
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
CtrlClearHaltFeature();
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
break;
case IN_OK_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
case OUT_TOKEN:
default:
pSotaUsbRequest->InProgress = false;
break;
}
}
//----------------------------------------------------------------------------
// Sync Frame Request
//----------------------------------------------------------------------------
void CtrlReqSyncFrame()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
// We do not support isochronous mode.
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
break;
case IN_OK_TOKEN:
case IN_TOKEN:
case OUT_TOKEN:
default:
pSotaUsbRequest->InProgress = false;
break;
}
}
//----------------------------------------------------------------------------
// Get Max Lun Request
//----------------------------------------------------------------------------
void CtrlReqGetMaxLun()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
pSotaUsbRequest->LoadInDataOk = true;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0_STL);
break;
case IN_TOKEN:
if (pSotaUsbRequest->LoadInDataOk)
{
CSRWrite(USB_BASE + EP0_TXCNT, 1);
CSRWrite(USB_BASE + EP0_TXDATA, LastDevice);
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;
}
}
//----------------------------------------------------------------------------
// Bulk Only Reset Request
//----------------------------------------------------------------------------
void CtrlReqBulkReset()
{
BYTE Token = pSotaUsbRequest->Token;
switch(Token)
{
case SETUP_TOKEN:
#ifndef CTRL_SIMULATION
BulkState = CBW_GET_COMPLETED;
CmdStatus = COMMAND_PASSED;
#endif
break;
case IN_TOKEN:
CSRWrite(USB_BASE + EP0_TXCNT, 0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0);
break;
case IN_OK_TOKEN:
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
case OUT_TOKEN:
default:
// Ctrl Read End
pSotaUsbRequest->InProgress = false;
break;
}
}
//----------------------------------------------------------------------------
// Request Setup
//----------------------------------------------------------------------------
void CtrlReqSetup()
{
PUSB_REQUEST pReq = &(pSotaUsbRequest->Request);
memcpy((void *)pReq, (void *)UsbBuf, sizeof(USB_REQUEST));
pSotaUsbRequest->InProgress = true;
pSotaUsbRequest->FinishedDataLen = 0;
pReq->wLength = ConvertEndian16(pReq->wLength);
}
//----------------------------------------------------------------------------
// Rx Transation Check
//----------------------------------------------------------------------------
void CtrlRxCheck()
{
BYTE i;
BYTE Len;
BYTE RxTokenType = 0;
Len = CSRRead(USB_BASE + EP0_RXCNT);
for (i=0; i < Len; i++)
{
UsbBuf[i] = CSRRead(USB_BASE + EP0_RXDATA);
}
RxTokenType = CSRRead(USB_BASE + EP0_RXTOKEN);
if (RxTokenType & (STS_SETUP0 | STS_SETUP0_OW))
{
if (Len == USB_REQUEST_LEN)
{
CtrlReqSetup();
pSotaUsbRequest->Token = SETUP_TOKEN;
}
else
{
pSotaUsbRequest->Token = BAD_SETUP_TOKEN;
}
// Add delay may resolve SE1 issue if using H/W incurred this issue.
// Delay(30);
}
else // Out Token Coming
pSotaUsbRequest->Token = OUT_TOKEN;
CSRWrite(USB_BASE + EP0_RXTOKEN, 0x00);
}
//--------------------------------------------------------------------
//
//--------------------------------------------------------------------
void CtrlRequestProcess()
{
BYTE RequestCode = pSotaUsbRequest->Request.bRequest;
BYTE RequestType = pSotaUsbRequest->Request.bmRequestType;
if((RequestType & 0x60) == 0) // Standard Request
{
switch (RequestCode)
{
case GET_STATUS : CtrlReqGetStatus(); return;
case CLEAR_FEATURE : CtrlReqClearFeature(); return;
case SET_FEATURE : CtrlReqSetFeature(); return;
case SET_ADDRESS : CtrlReqSetAddress(); return;
case GET_DESCRIPTOR : CtrlReqGetDescriptor(); return;
case GET_CONFIGURATION: CtrlReqGetConfiguration(); return;
case SET_CONFIGURATION: CtrlReqSetConfiguration(); return;
case GET_INTERFACE : CtrlReqGetInterface(); return;
case SET_INTERFACE : CtrlReqSetInterface(); return;
case SYNCH_FRAME : CtrlReqSyncFrame(); return;
}
}
else if((RequestType & 0x60) == 0x20) // Class Request
{
switch (RequestCode)
{
case BULKONLY_GET_MAX_LUN: CtrlReqGetMaxLun(); return;
case BULKONLY_RESET : CtrlReqBulkReset(); return;
}
}
pSotaUsbRequest->InProgress = false;
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
CSRWrite(USB_BASE + EP0_TXCSR, EN_TX0_STL);
}
//----------------------------------------------------------------------------
// Ctrl Pipe Check
//----------------------------------------------------------------------------
void UsbCtrlIntHandler(BYTE IntEvent)
{
// Clear IRQs.
CSRWrite(USB_BASE + EPIE, ~IntEvent);
if (IntEvent & IRQ_IN0)
{
pSotaUsbRequest->Token = IN_TOKEN;
CSRWrite(USB_BASE + EP0_RXCSR, 0); // Fix the PHY miss IN ACK problem
}
if (IntEvent & IRQ_TX0) // This irq mean IN packet Completed
pSotaUsbRequest->Token = IN_OK_TOKEN;
if (IntEvent & IRQ_RX0)
CtrlRxCheck();
if (pSotaUsbRequest->InProgress)
CtrlRequestProcess();
else
CSRWrite(USB_BASE + EP0_RXCSR, EN_RX0);
}
//----------------------------------------------------------------------------
// Init USB
//----------------------------------------------------------------------------
void UsbInit()
{
BYTE Reg;
CtrlPktSize = CTRL_PKT_SIZE;
CSRWrite(USB_BASE + EPIM, 0xdf);
CSRWrite(USB_BASE + EPCTL, EN_EP0 | EN_EP1 | EN_EP2);
pSotaUsbRequest = &SotaUsbRequest;
pSotaUsbRequest->InProgress = false;
pSotaUsbRequest->LoadInDataOk = false;
pSotaUsbRequest->HaltStatus = false;
InitBulkPipe();
while(1) // Detect USB Link Speed
{
Reg = CSRRead(USB_BASE + USB_SPEED);
if(Reg & SPEED_READY)
break;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -