?? sc2410_usb_hw.c
字號:
}
UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
}
// Command is complete
sendDone(pHWHead,0);
//RETAILMSG(1, (TEXT("SF[0x%X]\r\n"), pHWHead->dReq.wIndex & 0xFF));
break;
case SET_ADDRESS:
RETAILMSG(1, (TEXT("SET_ADDRESS - 0x%X\r\n"), pHWHead->dReq.wValue));
pHWHead->dAddress = (BYTE)pHWHead->dReq.wValue;
// Note, this write needs to be started here but it will not read back
// until the command completes. There is no retry mechanism.
setAddress(pHWHead, pHWHead->dAddress);
// Command is complete
sendDone(pHWHead,0);
break;
case GET_DESCRIPTOR:
switch ((BYTE)(pHWHead->dReq.wValue>>8)) {
case DEVICE: // 0x01
RETAILMSG(1, (TEXT("GET_DESCRIPTOR:DEVICE 0x%X, 0x%X\r\n"),
uStd[0], pHWHead->dReq.wLength));
//sendCommandDone(pHWHead);
p = (PUCHAR)uStd;
len = (BYTE)min(uStd[0],pHWHead->dReq.wLength);
totLen = uStd[0];
break;
case CONFIGURATION: // 0x02
RETAILMSG(1,(TEXT("GET_DESCRIPTOR:CONFIGURATION\r\n")));
//sendCommandDone(pHWHead);
p = (PUCHAR)&uStd[iCONF];
len = (BYTE)min(CFGLEN,pHWHead->dReq.wLength);
totLen = CFGLEN;
break;
case STRING: // 0x03
DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:STRING\r\n")));
//sendCommandDone(pHWHead);
p = NULL;
len = 0;
totLen = 0;
break;
default:
DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:Unknown %d\r\n"),
(pHWHead->dReq.wValue>>8) ));
sendCommandDone(pHWHead);
p = NULL;
len = 0;
totLen = 0;
break;
}
// Clear the OPR bit and start the data phase
sendCommandDone(pHWHead);
// Send the reply data.
sendData(pHWHead, p, len, totLen);
DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:EP0ICSR1 status value = 0x%x\r\n"), pHWHead->pUSBCtrlAddr->EP0ICSR1));
break;
case GET_CONFIG:
RETAILMSG(1, (TEXT("GET_CONFIG\r\n")));
// Clear the OPR bit and start the data phase
sendCommandDone(pHWHead);
// Send the reply data.
sendData(pHWHead, &pHWHead->dConfIdx, 1, 1);
break;
case GET_INTERFACE:
DEBUGMSG(1,(TEXT("GET_INTERFACE\r\n")));
// Clear the OPR bit and start the data phase
sendCommandDone(pHWHead);
// Send the reply data.
sendData(pHWHead, &pHWHead->dInterface, 1, 1);
break;
case SET_CONFIG:
RETAILMSG(1,(TEXT("SET_CONFIG %d\r\n"),
pHWHead->dReq.wValue));
pHWHead->dConfIdx = (BYTE)pHWHead->dReq.wValue;
// Command done
sendDone(pHWHead,0);
break;
case SET_DESCRIPTOR:
RETAILMSG(1, (TEXT("SET_DESCRIPTOR\r\n")));
// Command done
sendDone(pHWHead,0);
break;
case SET_INTERFACE:
DEBUGMSG(1,(TEXT("SET_INTERFACE : %d,%d\r\n"),
pHWHead->dReq.wIndex,
pHWHead->dReq.wValue));
pHWHead->dInterface = (BYTE)pHWHead->dReq.wIndex;
pHWHead->dSetting = (BYTE)pHWHead->dReq.wValue;
// Command done
sendDone(pHWHead,0);
break;
default:
DEBUGMSG(1,(TEXT("Unhandled Command : %d\r\n"),
pHWHead->dReq.bRequest));
// Command done
sendDone(pHWHead,0);
break;
}
}
DEBUGMSG(1, (TEXT("--SC2410_USB_DoEndpoint0\r\n")));
}
/*************************************************************************
SC2410_USB_GetInterruptType
Determine the source of an interrupt and return flags to control
which function gets called to handle it. EP0 is handled as modem
interrupt, EP1 as TX, EP3 as RX and reset is handle as line
interrupt.
*************************************************************************/
INTERRUPT_TYPE SC2410_USB_GetInterruptType( PSER_INFO pHWHead) //:-)
{
INTERRUPT_TYPE interruptFlags = 0;
//BYTE saveIndex;
pHWHead->wPrevSOF = pHWHead->wSOF;
pHWHead->wSOF = (pHWHead->pUSBCtrlAddr->FNR2.fr_n2 << 8) | pHWHead->pUSBCtrlAddr->FNR1.fr_n1;
//DEBUGMSG(1, (TEXT("SOF: %u, wPrevSOF: %u\r\n"), pHWHead->wSOF, pHWHead->wPrevSOF));
//RETAILMSG(1, (TEXT("SOF: %u, wPrevSOF: %u\r\n"), pHWHead->wSOF, pHWHead->wPrevSOF));
///pHWHead->cIntStat_uir = *(BYTE *)&pHWHead->pUSBCtrlAddr->UIR;
///pHWHead->cIntStat_eir = *(BYTE *)&pHWHead->pUSBCtrlAddr->EIR;
///RETAILMSG(1,(TEXT("::: cIntStat_uir = %d\r\n"), pHWHead->cIntStat_uir));
///RETAILMSG(1,(TEXT("::: cIntStat_eir = %d\r\n"), pHWHead->cIntStat_eir));
//important notes
// 1. INDEX register should be preserved here. //:-)
// 2. 'else if' should not be used here. //:-)
if (usbdShMem->usbdEir& USBDEIR_EP1) // EP1(IN), ready to TX more data.
{
interruptFlags |= INTR_TX;
}
//jocky
if (usbdShMem->usbdEir& USBDEIR_EP4)//&& (!usbdShMem->usbSwitch)) // EP4(OUT), RX data ready
{
interruptFlags |= INTR_RX;
}
//jocky
if (usbdShMem->usbdDma3Int) // DMA3 done interrupt
{
interruptFlags |= INTR_RX;
USBDMSG(1, (TEXT("<D3Int>\r\n")));
}
if (usbdShMem->usbdUir&USBDUIR_RESET)// USB reset, so re-initialize our driver.
{
USBDMSG(1, (TEXT("RESET INT\r\n")));
interruptFlags |= INTR_LINE; // We use INTR_LINE to handle USB Reset
usbdShMem->usbdUir&=~USBDUIR_RESET;
}
if (usbdShMem->usbdEir&USBDEIR_EP0) // EP0, Control endpoint
{
interruptFlags |= INTR_MODEM; // Use INTR_MODEM for EP0 interrupts
// call SerModemIntr function by shim 020503
usbdShMem->usbdEir&=~USBDEIR_EP0;
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x0;
//temp_kiw, should be repaired officially.
USBDMSG(1, (TEXT("<EP0 Int>\r\n")));
}
return (interruptFlags);
}
/*************************************************************************
SC2410_USB_LineIntHandler
This handler is called for reset interrupts
*************************************************************************/
void SC2410_USB_LineIntHandler(PSER_INFO pHWHead)
{
ULONG WaitReturn; //Jonathan
DEBUGMSG(1, (TEXT("++SC2410_USB_LineIntHandler\r\n")));
SC2410_USB_Init(pHWHead);
UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
//Jonathan01_0915 Start
if(pDriverGlobals->misc.InitUSBClient == 0)
{
pDriverGlobals->misc.InitUSBClient = 1;
//eltR04_01 s2410IOP->rGPBCON &= ~(0x3 << 6);
pDriverGlobals->misc.USBCableEvent =0;//maggie03
pHWHead->ModemStatus &= ~MS_RLSD_ON;
EvaluateEventFlag(pHWHead->pMddHead, EV_RLSD);
//make a delay
WaitReturn = WaitForSingleObject(pHWHead->hSerialEvent, 0x00001000L);
if(!(s2410IOP->rGPGDAT & (0x1 << 1)) && (s2410IOP->rGPGDAT & (0x1 << 8)))
{
s2410IOP->rGPJDAT |= (0x1 << 9);
pDriverGlobals->misc.USBCableEvent =1;
RETAILMSG(1,(TEXT("::: SC2400_USB_LineIntHandler -- USB IN \r\n")));
}
//RETAILMSG(1,(TEXT("::: SC2400_USB_LineIntHandler A\r\n")));
}
//Jonathan01_0915 end
DEBUGMSG(1, (TEXT("--SC2410_USB_LineIntHandler\r\n")));
}
/*************************************************************************
SC2410_USB_RxIntHandler
Read characters up to the max packet length from the IN FIFO. Return the
number of characters read in the supplied argument. The function returns
a boolean indicating whether event characters are present.
*************************************************************************/
BOOL SC2410_USB_RxIntHandler(PSER_INFO pHWHead,
PUCHAR pRxBuffer,
ULONG *pBuffLen)
{
BOOL fRXFlag = FALSE;
UCHAR cEvtChar = pHWHead->dcb.EvtChar;
int buflen = *pBuffLen;
UCHAR cRxChar;
ULONG usbdRxRdPt=0;
ULONG usbdRxWrPt=0;
//ULONG usbdRxCnt;
int usbdRxCnt;
BYTE* usbdRxBuf;
//ULONG cnt,saveCnt;
ULONG saveCnt;
int cnt;
int swRdCnt=0;
BYTE saveIndex;
int i=0;
ULONG uNewusbdRxWrPt=0;
DEBUGMSG(1, (TEXT("++SC2410_USB_RxIntHandler\r\n")));
usbdRxRdPt=usbdShMem->usbdRxRdPt;
usbdRxBuf=(BYTE*)usbdShMem->usbdRxBuf;
*pBuffLen = 0;
// Endpoint 4 mode
saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x4;
if (usbdShMem->usbdDma3Int)
{
USBDMSG(1,(TEXT("[RxPt:%d]"),usbdRxRdPt));
if(usbdRxRdPt==0)
{
usbdShMem->usbdDma3Int=0;
bWritefull=FALSE;
USBDMSG(1,(TEXT("[D:%d"),pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low));
UsbdInitDma3(0,0);
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTL=(USBD_GLOBALS_BUF_SIZE-swRdCnt)&0xff;
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTM=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>8)&0xff;
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTH=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>16)&0x0f;
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
Sleep(1);//wait DMA ready
}
}
for(i=0; i<1000; i++)
{
usbdRxWrPt=v_pDMAregs->rDCDST3 - realPhysicalAddr_UsbdRxBuf;
if(usbdRxWrPt==USBD_GLOBALS_BUF_SIZE)
{
bWritefull=TRUE;
}
if(bWritefull)
usbdRxCnt=USBD_GLOBALS_BUF_SIZE-usbdRxRdPt;
else
usbdRxCnt=usbdRxWrPt-usbdRxRdPt;
if( buflen < usbdRxCnt)
{
saveCnt=cnt=buflen;
break;
}
else
saveCnt=cnt=usbdRxCnt;
}
if (usbdRxCnt == 0) // No data to read
{
USBDMSG(1, (TEXT("[R0]")));
}
else
{
USBDMSG(1, (TEXT("<%d>"),cnt));
while(cnt--)
{
*pRxBuffer++ = cRxChar = (UCHAR)usbdRxBuf[usbdRxRdPt++];
if(usbdRxRdPt==USBD_GLOBALS_BUF_SIZE)
usbdRxRdPt=0;
if( cRxChar == cEvtChar )
fRXFlag = TRUE;
}
(*pBuffLen)=saveCnt;
usbdRxCnt-=saveCnt;
usbdShMem->usbdRxRdPt=usbdRxRdPt;
usbdShMem->usbdEir&=~USBDEIR_EP4;
}
//not be needed. Only for test
/* if(pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low==0 )
if(pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
{
USBDMSG(1, (TEXT("__OPR__(NEVER EXECUTED)")));
UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
}
*/
// If we didn't read the whole buffer we need to come back. Leave with
// the interrupt still enabled so the MDD will recall.
uNewusbdRxWrPt=v_pDMAregs->rDCDST3 - realPhysicalAddr_UsbdRxBuf;//Jason0315
// if (usbdRxCnt>0)//Jason0315
if((usbdRxCnt>0)||uNewusbdRxWrPt>usbdRxWrPt)//Jason0315
{
USBDMSG(1, (TEXT("[%d->MDD]"),usbdRxCnt));
usbdShMem->usbdEir|=USBDEIR_EP4;
// MDD will recall RxIntHandler by chekcing SC2410_USB_GetInterruptType().
// So, usbdShMem->usbdEir:USBDEIR_EP3 must not be cleared //:-)
//Sleep(100);
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return fRXFlag;
}
usbdShMem->usbdEir&=~USBDEIR_EP4;
DEBUGMSG(1, (TEXT("--SC2410_USB_RxIntHandler\r\n")));
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return fRXFlag;
}
/*************************************************************************
SC2410_USB_TxIntHandler
Send the next packet to the USB. The first packet gets sent by directly
calling this function (via dispatch table) from the MDD. After the first
call the interrupt mechanism will keep things going.
We return the actual number of bytes we've queued to the UDC. Note that
until the next interrupt we wont know if it has been transmitted. We'll
deal with the failure by saving the original packet and retransmitting if
we get an error. In that case we'll return 0 as the number of bytes sent
since no new bytes have been consumed from the caller's buffer.
When the packet is accepted we return the number of bytes and grab the
next packet (or portion thereof).
*************************************************************************/
//:-)
void SC2410_USB_TxIntHandler( PSER_INFO pHWHead,
PUCHAR pTxBuffer,
ULONG *pBuffLen )
{
unsigned int i;
UCHAR ucLen;
BYTE saveIndex;
//DEBUGMSG(1, (TEXT("++SC2410_USB_TxIntHandler\r\n")));
//USBDMSG(1, (TEXT("<T:%d>"),*pBuffLen));
usbdShMem->usbdEir&=~USBDEIR_EP1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -