📄 sc2450pdd.cpp
字号:
}
#if TEST_MODE_SUPPORT
static BOOL
CheckForUSBTestModeRequest(PCTRLR_PDD_CONTEXT pContext)
{
bool fTest = FALSE;
WORD test_temp;
// is this a request to enter a test mode?
//RETAILMSG(1, (_T("e\r\n")));
if( pContext->udr.bmRequestType == (USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_STANDARD | USB_REQUEST_FOR_DEVICE)
&& pContext->udr.bRequest == USB_REQUEST_SET_FEATURE
&& pContext->udr.wValue == USB_FEATURE_TEST_MODE
&& (pContext->udr.wIndex & 0xFF) == 0) {
pContext->sendDataEnd = TRUE;
pContext->Ep0State = EP0_STATE_IDLE;
#if 1
//RETAILMSG(1, (_T("USB_FEATURE_TEST_MODE\r\n")));
// Set TEST MODE
Sleep(1);
test_temp = ReadReg(pContext, TR);
test_temp |=TR_TMD;
WriteReg(pContext, TR, test_temp);
test_temp = ReadReg(pContext, TR);
USHORT wTestMode = pContext->udr.wIndex >> 8;
switch( wTestMode)
{
case USB_TEST_J:
//RETAILMSG(1, (_T("USB_TEST_J\r\n")));
//Set Test J
test_temp |=TR_TJS;
WriteReg(pContext, TR, test_temp);
break;
case USB_TEST_K:
//RETAILMSG(1, (_T("USB_TEST_K\r\n")));
//Set Test K
test_temp |=TR_TKS;
WriteReg(pContext, TR, test_temp);
break;
case USB_TEST_SE0_NAK:
//RETAILMSG(1, (_T("USB_TEST_SE0_NAK\r\n")));
//Set Test SE0NAK
test_temp |=TR_TSNS;
WriteReg(pContext, TR, test_temp);
break;
case USB_TEST_PACKET:
DWORD cbWritten = 0;
WORD WriteData = 0;
volatile ULONG *pulFifoReg = _GetDataRegister(0);
PBYTE pbBuffer = (PBYTE) ahwTestPkt;
//RETAILMSG(1, (_T("USB_TEST_PACKET\r\n")));
// Test Packet Size is 53 Bytes in Spec,, and Our USB FIFO support 2ByteAccess
//SO TestPacketSize is 53, FIFO Write size is 54
WriteIndexedReg(pContext, 0, BWCR, TEST_PKT_SIZE);
for (cbWritten = 0; cbWritten < TEST_ARR_SIZE ; cbWritten++) {
WriteData=ahwTestPkt[cbWritten];
*pulFifoReg = WriteData;
}
test_temp |=TR_TPS;
WriteReg(pContext, TR, test_temp);
break;
}
#endif
fTest = TRUE;
}
return fTest;
}
#endif
VOID
HandleEndpoint0Event(
PCTRLR_PDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
DEBUGCHK(pContext->fRunning);
PEP_STATUS peps = GetEpStatus(pContext, 0);
LOCK_ENDPOINT(peps);
ClearEndpointInterrupt(pContext, 0);
WORD bUSBBusIrqStat = ReadReg(pContext, SSR);
WORD bEP0IrqStatus = ReadReg(pContext, EP0SR);
WORD bSCR = ReadReg(pContext, SCR);
WORD bEP0CR = ReadReg(pContext, EP0CR);
// Write 0 to SEND_STALL and SENT_STALL to clear them, so we need to
// leave them unchanged by default.
BYTE bEp0CsrToWrite = 0;
// Set By USB if protocol violation detected
if (bEP0IrqStatus & EP0SHT) {
// Must Clear both Send and Sent Stall
SetClearReg(pContext, EP0SR, EP0SHT, SET);
SetClearReg(pContext, EP0CR, EP0ESS, CLEAR);
if (bEP0IrqStatus & EP0RSR)
SetClearReg(pContext, EP0SR, EP0RSR, SET);
pContext->Ep0State = EP0_STATE_IDLE;
}
if (bEP0IrqStatus & EP0TST) {
// Must Clear both Send and Sent Stall
SetClearReg(pContext, EP0SR, EP0TST, SET);
}
BOOL fSendUdr = FALSE;
DWORD cbFifo = ReadIndexedReg(pContext, 0, BRCR);
BOOL fCompleted = FALSE;
DWORD dwStatus;
// setup packet
if (pContext->Ep0State == EP0_STATE_IDLE) {
if (bEP0IrqStatus & EP0RSR) {
// New setup packet
const DWORD cbOutFifo = ReadIndexedReg(pContext, 0, BRCR);
// 16bit Buffer Interface
PWORD pbUdr = (PWORD) &pContext->udr;
volatile ULONG *pulFifoReg = _GetDataRegister(0);
DWORD cbBytesRemaining = cbOutFifo;
while (cbBytesRemaining--) {
*pbUdr = (WORD) *pulFifoReg;
pbUdr ++;
}
SetClearReg(pContext, EP0SR, EP0RSR, SET);
#if TEST_MODE_SUPPORT
if(!CheckForUSBTestModeRequest(pContext)){ //for testmode
#else
if(TRUE){
#endif
// Determine if this is a NO Data Packet
if (pContext->udr.wLength > 0) {
// Determine transfer Direction
if (pContext->udr.bmRequestType & USB_ENDPOINT_DIRECTION_MASK) {
// Start the SW IN State Machine
pContext->Ep0State = EP0_STATE_IN_DATA_PHASE;
RETAILMSG(DBG, (_T("%s EP0_STATE_IN_DATA_PHASE\r\n"), pszFname));
}
else {
// Start the SW OUT State Machine
pContext->Ep0State = EP0_STATE_OUT_DATA_PHASE;
RETAILMSG(DBG, (_T("%s EP0_STATE_OUT_DATA_PHASE\r\n"), pszFname));
}
pContext->sendDataEnd = FALSE;
}
else { // udr.wLength == 0
// ClientDriver will issue a SendControlStatusHandshake to
// complete the transaction.
pContext->sendDataEnd = TRUE;
// Nothing left to do... stay in IDLE.
DEBUGCHK(pContext->Ep0State == EP0_STATE_IDLE);
}
fSendUdr = TRUE;
}
}
else{
WriteIndexedReg(pContext, 0, EP0SR, bEP0IrqStatus);//for RNDIS Class,
}
}
// Data Out Packet
else if (pContext->Ep0State == EP0_STATE_OUT_DATA_PHASE) {
if (bEP0IrqStatus & EP0RSR) {
// Check For out packet read && receive fifo not empty -> out token event
if (cbFifo) {
DEBUGMSG(ZONE_RECEIVE, (_T("%s out token packet on endpoint 0 \r\n"),
pszFname));
HandleRx(pContext, peps, &fCompleted, &dwStatus);
}
// status stage of control transfer; zero-length packet received
else {
DEBUGMSG(ZONE_RECEIVE, (_T("%s status stage of control transfer on endpoint 0\r\n"),
pszFname));
pContext->Ep0State = EP0_STATE_IDLE;
}
}
else
RETAILMSG(DBG, (_T("Not RST in outdataphase: 0x%08x =========\r\n"),bEP0IrqStatus ));
}
// Data In Packet
else {
HandleTx(pContext, peps, 0);
}
if (fCompleted) {
CompleteTransfer(pContext, peps, dwStatus);
}
if (fSendUdr) {
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &pContext->udr);
}
FUNCTION_LEAVE_MSG();
UNLOCK_ENDPOINT(peps);
}
#define DBG_TEST3 1
// Process an endpoint interrupt. Call interrupt-specific handler.
static
VOID
HandleEndpointEvent(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint,
DWORD epIrqStat
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
DEBUGCHK(pContext->fRunning);
DEBUGCHK(dwEndpoint != 0);
DWORD dwPendingEvents = 0;
EP_STATUS *peps = GetEpStatus(pContext, dwEndpoint);
PREFAST_DEBUGCHK(peps);
LOCK_ENDPOINT(peps);
ClearEndpointInterrupt(pContext, dwEndpoint);
WORD bEpIrqStat;
bEpIrqStat = ReadIndexedReg(pContext, dwEndpoint, ESR);
if (peps->dwDirectionAssigned == USB_IN_TRANSFER) {
// Stall "acknowledged" from Host
if (bEpIrqStat & FSC) {
USB_DEVICE_REQUEST udr;
udr.bmRequestType = USB_REQUEST_FOR_ENDPOINT;
udr.bRequest = USB_REQUEST_CLEAR_FEATURE;
udr.wValue = USB_FEATURE_ENDPOINT_STALL;
udr.wIndex = USB_ENDPOINT_DIRECTION_MASK | (BYTE) dwEndpoint;
udr.wLength = 0;
DisableEndpointInterrupt(pContext, dwEndpoint);
DEBUGMSG(ZONE_PIPE, (_T("%s Got IN_SENT_STALL EP%u \r\n"),
pszFname, dwEndpoint));
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &udr);
// Must Clear both Send and Sent Stall
SetClearIndexedReg(pContext, dwEndpoint, ESR, FSC, SET);
}
if (bEpIrqStat & TPS) {
// Must Clear Tx Packet Success
WriteIndexedReg(pContext, dwEndpoint, ESR, bEpIrqStat);
dwPendingEvents = IN_TRANSFER;
}
}
else {
// Stall "acknowledged" from Host
if (bEpIrqStat & FSC) {
USB_DEVICE_REQUEST udr;
udr.bmRequestType = USB_REQUEST_FOR_ENDPOINT;
udr.bRequest = USB_REQUEST_CLEAR_FEATURE;
udr.wValue = USB_FEATURE_ENDPOINT_STALL;
PREFAST_SUPPRESS(12006, "Buffer access index expression 'udr.wIndex=(USHORT)dwEndpoint' is being truncated in a shortening cast.");
udr.wIndex = (USHORT) dwEndpoint;
udr.wLength = 0;
DisableEndpointInterrupt(pContext, dwEndpoint);
DEBUGMSG(ZONE_PIPE, (_T("%s Got OUT_SENT_STALL EP%u \r\n"),
pszFname, dwEndpoint));
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_SETUP_PACKET, (DWORD) &udr);
// Must Clear both Send and Sent Stall
SetClearIndexedReg(pContext, dwEndpoint, ESR, FSC, SET);
}
if (bEpIrqStat & FFS) {
// Must Clear FIFO Flushed
SetClearReg(pContext, ESR, FFS, SET);
}
if (bEpIrqStat & RPS) {
// Rx Packet Success is automatically cleared when MCU reads all packets
dwPendingEvents = OUT_TRANSFER;
}
}
BOOL fCompleted = FALSE;
DWORD dwStatus;
if (dwPendingEvents == IN_TRANSFER) {
HandleTx(pContext, peps, 0);
}
else if (dwPendingEvents == OUT_TRANSFER) {
HandleRx(pContext, peps, &fCompleted, &dwStatus);
}
if (fCompleted) {
// Disable transfer interrupts until another transfer is issued.
DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
}
if (fCompleted) {
CompleteTransfer(pContext, peps, dwStatus);
}
FUNCTION_LEAVE_MSG();
UNLOCK_ENDPOINT(peps);
}
// Process USB Bus interrupt
VOID
HandleUSBBusIrq(
PCTRLR_PDD_CONTEXT pContext,
WORD bUSBBusIrqStat
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
if (bUSBBusIrqStat & VBUSON) {
SetClearReg(pContext, SSR, VBUSON, SET);
}
if (bUSBBusIrqStat & SSRINTERR) {
SetClearReg(pContext, SSR, SSRINTERR, SET);
}
if (bUSBBusIrqStat & SDE) {
SetClearReg(pContext, SSR, SDE, SET);
if(bUSBBusIrqStat & HSP){
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_SPEED,
BS_HIGH_SPEED);
RETAILMSG(1, (_T("HIGH Speed\r\n")));
}
else {
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_SPEED,
BS_FULL_SPEED);
RETAILMSG(1, (_T("FULL Speed\r\n")));
}
}
if (bUSBBusIrqStat & HFSUSP) {
SetClearReg(pContext, SSR, HFSUSP, SET);
RETAILMSG(0, (_T("%s Suspend_temp\r\n"), pszFname));
if(pContext->attachedState == UFN_ATTACH)
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_SUSPEND);
}
if (bUSBBusIrqStat & HFRM) {
SetClearReg(pContext, SSR, HFRM, SET);
RETAILMSG(0, (_T("%s Resume_temp\r\n"), pszFname));
if(pContext->attachedState == UFN_ATTACH)
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_RESUME);
}
if (bUSBBusIrqStat & HFRES) {
SetClearReg(pContext, SSR, HFRES, SET);
DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Reset\r\n"), pszFname));
pContext->fSpeedReported = FALSE;
RETAILMSG(0, (_T("%s Reset\r\n"), pszFname));
if (pContext->attachedState == UFN_DETACH){
RETAILMSG(0, (_T("%s Reset_Attach\r\n"), pszFname));
if(USBClassInfo == USB_MSF){
Sleep(1000); //for MSF Class. on booting, to generate SD Detect INT and to to mount before storage detectetcion on BOT
if(bSDMMCMSF && (v_gBspArgs->g_SDCardState == CARD_INSERTED)){
RETAILMSG(1,(TEXT("Reset_MSFCardInserted\r\n")));
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
pContext->attachedState = UFN_ATTACH;
}
else if(bSDMMCMSF && (v_gBspArgs->g_SDCardState == CARD_REMOVED))
{
RETAILMSG(1,(TEXT("Reset_MSFCardRemoved\r\n")));
pIOPregs->GPHCON = (pIOPregs->GPHCON & ~(0x3<<28)) | (0x1<<28);
pIOPregs->GPHUDP = (pIOPregs->GPHUDP & ~(0x3<<28)) | (0x2<<28);
pIOPregs->GPHDAT = (pIOPregs->GPHDAT & ~(0x1<<14));
}
}
else{
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
pContext->attachedState = UFN_ATTACH;
}
}
pContext->Ep0State = EP0_STATE_IDLE;
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
}
FUNCTION_LEAVE_MSG();
}
// Process a SC2450 interrupt.
VOID
HandleUSBEvent(
PCTRLR_PDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
WORD nStop = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -