📄 bvd_udc_hw.c
字号:
//pRxWord++;
pData[0] = (BYTE) (rx_word1 & 0xFF);
pData[1] = (BYTE) ((rx_word1>>8) & 0xFF);
pData[2] = (BYTE) ((rx_word1>>16) & 0xFF);
pData[3] = (BYTE) ((rx_word1>>24) & 0xFF);
pData +=4;
word_count--;
}
}
if (byte_count)
{
//temp_byte_count = byte_count;
rx_word1 = UDC_DR_0( pHWHead );
//while (temp_byte_count)
//{
// pData[0] = (BYTE) (rx_word1 & 0xFF);
// pData++;
// rx_word1 = (rx_word1>>8);
// temp_byte_count--;
//}
if (byte_count == 1)
{
pData[0] = (BYTE) (rx_word1 & 0xFF);
}
else if (byte_count == 2)
{
pData[0] = (BYTE) (rx_word1 & 0xFF);
pData[1] = (BYTE) ((rx_word1>>8) & 0xFF);
}
else if (byte_count == 3)
{
pData[0] = (BYTE) (rx_word1 & 0xFF);
pData[1] = (BYTE) ((rx_word1>>8) & 0xFF);
pData[2] = (BYTE) ((rx_word1>>16) & 0xFF);
}
pData+= byte_count;
byte_count -= byte_count;
}
UDCTrace( pHWHead, UDCT_GET_COMMAND, (unsigned long)pData - (unsigned long)dataP ); // bpc: pD-dP was nTotalBytes
udcStats.readCount++;
return 0;
}
BOOL UsbRequestGetStringDescriptor(XLLP_UINT16_T wValue, XLLP_UINT8_T **txDatP, XLLP_UINT8_T *txDatLen)
{
XLLP_UINT16_T descriptorIndex;
P_XLLP_UINT8_T stringDescriptor;
descriptorIndex = USBData_LowByte (wValue); // get the descriptor index in the low byte
if (descriptorIndex <= lastStringIndex)
{
switch (descriptorIndex)
{
case languagesStringIndex:
stringDescriptor = (P_XLLP_UINT8_T)LanguagesStringDescriptor;
break;
case manufactureStringIndex:
stringDescriptor = (P_XLLP_UINT8_T)ManufactureStringDescriptor;
break;
case productStringIndex:
stringDescriptor = (P_XLLP_UINT8_T)ProductStringDescriptor;
break;
/*
case configurationStringIndex:
stringDescriptor = (UsbStringDescriptorPtr) & ConfigurationStringDescriptor;
break;
case interfaceStringIndex:
stringDescriptor = (UsbStringDescriptorPtr) & InterfaceStringDescriptor;
break;
case SerialNumberStringIndex:
stringDescriptor = (UsbStringDescriptorPtr) & SerialNumberStringDescriptor;
break;
*/
}
*txDatLen = stringDescriptor[0];
*txDatP = stringDescriptor;
return TRUE;
}
else
{
return FALSE;
}
}
/*
* getCommandEightBytes
*
* Read 8 Bytes from the endpoint 0 FIFO
*
* Returns 1 if read failed,
* 0, success
*/
static
int getCommandEightBytes(PSER_INFO pHWHead, void * dataP)
{
unsigned long * bufP_a = (unsigned long*) dataP;
unsigned int nTotalBytes = 8;
//DWORD dwFrame;
//unsigned int *bufP_b = (unsigned char*) dataP;
memset(bufP_a,0x55,8);
// Include the frame numbers on each trace instead of the signature.
//dwFrame = (UDC_FNR(pHWHead) & 0x7ff);
while (nTotalBytes)
{
*bufP_a++ = (unsigned long) UDC_DR_0(pHWHead);
nTotalBytes =-4;
}
/*
nTotalBytes = 8;
bufP_b = (unsigned char*)dataP;
NKDbgPrintfW(TEXT("0x81 Bytes :%x %x %x %x %x %x %x %x Frame:%d\r\n"),
bufP_b[0],bufP_b[1],bufP_b[2],bufP_b[3],
bufP_b[4],bufP_b[5],bufP_b[6],bufP_b[7], dwFrame);
UDCTrace( pHWHead, UDCT_GET_COMMAND, nTotalBytes );
udcStats.readCount++;
*/
return 0;
}
//
// SA_USB_Init
//
// Initialize the UDC.
//
extern
void SA_USB_Init(PSER_INFO pHWHead)
{
unsigned long udc_crA_val, udc_crB_val ;
// PUCHAR pVMem;
DEBUGMSG( ZONE_FUNCTION,
(TEXT("+SA_USB_Init\r\n")));
RETAILMSG(1, (TEXT("**************SA_USB_Init\r\n")));
pHWHead->dConfIdx = 0;
pHWHead->dSetting = 0;
pHWHead->dInterface = 0;
pHWHead->dAddress = 0;
pHWHead->ModemStatus = 0; // All lines low till we get connected.
//Enable UDC clock
pHWHead->pCLKRegs->cken |= XLLP_CLKEN_USBCLIENT;
//if (!(StartClock(CLK_USB,NOTINPOWERHANDLER)))
// DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to start USB clock!\r\n")));
//Configure endpoint registers
//Clear UDE
UDCCR_UDE_DISABLE( UDC_CR(pHWHead) );
//Configuring Endpoint A
//BULK IN with max pkt size 64
udc_crA_val = ( XLLP_UDC_UDCCRZ_EE | MAX_PKT_BULK_64 |
EP_DIRECTION_IN | EP_TYPE_BULK | EP_NUM_1 |
ALTERNATE_INTERFACE_SETTING_0 | INTERFACE_SETTING_0 | CONFIG_NUM_1 ) ;
#ifdef DISABLE_DOUBLE_BUFFER
//Disable double buffer
udc_crA_val &= ~(XLLP_UDC_UDCCRZ_DE);
#else
//Enable double buffer
udc_crA_val |= (XLLP_UDC_UDCCRZ_DE);
#endif
//Configure Endpoint A
ENDPOINT_A(pHWHead) = udc_crA_val;
//Configuring Endpoint B
//BULK OUT with max pkt size 64
udc_crB_val = ( XLLP_UDC_UDCCRZ_EE | MAX_PKT_BULK_64 |
EP_DIRECTION_OUT | EP_TYPE_BULK | EP_NUM_2 |
ALTERNATE_INTERFACE_SETTING_0 | INTERFACE_SETTING_0 | CONFIG_NUM_1 ) ;
#ifdef DISABLE_DOUBLE_BUFFER
//Disable double buffer
udc_crB_val &= ~(XLLP_UDC_UDCCRZ_DE);
#else
//Enable double buffer
udc_crB_val |= (XLLP_UDC_UDCCRZ_DE);
#endif
//Configure Endpoint B
ENDPOINT_B(pHWHead) = udc_crB_val;
//Enable UDE
UDCCR_UDE_ENABLE( UDC_CR(pHWHead) );
//Check for Endpoint Memory configuration error
if (UDC_CR(pHWHead) & XLLP_UDC_UDCCR_EMCE)
{
//We should not get here
//NKDbgPrintfW(TEXT("Error: UDC Endpoint Memory configuration error\r\n"));
//RETAILMSG(1, (TEXT("Error: UDC Endpoint Memory configuration error\r\n")));
ASSERT(0);
}
else
{
//NKDbgPrintfW(TEXT("UDC Endpoint Memory configured\r\n"));
//RETAILMSG(1, (TEXT("**************UDC Endpoint Memory configured\r\n")));
}
//Enable endpoint interrupts
//For endpoint 0, enable Packet Complete intr request and FIFO error intr request
//For endpoints A and B, enable Packet Complete intr request.
UDCICR0_INT_EN( UDC_ICR0(pHWHead), XLLP_UDC_UDCICR0_IE0_0 | /*XLLP_UDC_UDCICR0_IE0_1 |*/ // bpc stuff: no fifoerr ep0 handling
XLLP_UDC_UDCICR0_IEA_0 | XLLP_UDC_UDCICR0_IEB_0 );
//UDCICR0_INT_EN( UDC_ICR0(pHWHead), (XLLP_UDC_UDCICR0_IE0_0 | XLLP_UDC_UDCICR0_IE0_1 |
// XLLP_UDC_UDCICR0_IEA_0 | XLLP_UDC_UDCICR0_IEA_1 |
// XLLP_UDC_UDCICR0_IEB_0 | XLLP_UDC_UDCICR0_IEB_1 ));
//Enable Reset interrupt
UDCICR1_INT_EN( UDC_ICR1(pHWHead), XLLP_UDC_UDCICR1_IERS);
//Enable Config change intr
ENABLE_CONFIG_CHANGE_INTR(UDC_ICR1(pHWHead));
// Setup default state info.
UDC_STATE(pHWHead) = WAIT_FOR_SETUP;
//RETAILMSG( 1, (TEXT("UDC_CR_A: %X\r\n"), ENDPOINT_A(pHWHead) ));
//RETAILMSG( 1, (TEXT("UDC_CSR_A: %X\r\n"), UDC_CSR_A(pHWHead) ));
//RETAILMSG( 1, (TEXT("UDC_CR_B: %X\r\n"), ENDPOINT_B(pHWHead) ));
//RETAILMSG( 1, (TEXT("UDC_CSR_B: %X\r\n"), UDC_CSR_B(pHWHead) ));
// Setup trace information.
#ifdef UDC_TRACE
g_pTraceBuffer = VirtualAlloc( 0, PAGE_SIZE*PAGE_NUM, MEM_RESERVE, PAGE_NOACCESS );
if( g_pTraceBuffer == NULL )
return;
if( ! VirtualCopy( (LPVOID) g_pTraceBuffer, (LPVOID) UDC_PHYSICAL_TRACE_BUFFER, PAGE_SIZE*PAGE_NUM, PAGE_READWRITE | PAGE_NOCACHE))
{
g_pTraceBuffer = NULL;
return;
}
// Zero out the trace buffer.
memset( g_pTraceBuffer, 0, PAGE_SIZE );
g_pTraceBuffer[0] = 4;
#endif
//Detect cable state is connected or not
// if(pHWHead->pBCRReg->MISCRR1 & XLLP_BCR_MISCRR1_USB_CBL)
// {
// pHWHead->UDC_Reset = 1;
// pHWHead->UDC_ResetTimeOut = 5000; //Configuring it to 5sec for now
// }
//Enable UDC Soft Connect
// pHWHead->pBCRReg->MISCWR2 &= ~XLLP_BCR_MISCWR2_NUSBC_SC;
//NKDbgPrintfW(TEXT("-SA_USB_Init\r\n"));
RETAILMSG(1, (TEXT("**************-SA_USB_Init\r\n")));
DEBUGMSG( ZONE_FUNCTION,
(TEXT("-SA_USB_Init\r\n")));
}
/*
* SA_USB_DeInit
*
*
*/
void SA_USB_DeInit(
PSER_INFO pHWHead
)
{
//Disable UDC clock
//if (!(StopClock(CLK_USB,NOTINPOWERHANDLER)))
// DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to stop USB clock!\r\n")));
//Disable UDC clock
pHWHead->pCLKRegs->cken &= ~XLLP_CLKEN_USBCLIENT ;
}
/*----------------------------------------------------------------------------
* XmitEP0Data
*
* Transmits data to EP0. This makes sure that we don't have a premature
* status stage.
*----------------------------------------------------------------------------*/
void XmitEP0Data( PSER_INFO pHWHead )
{
int nXferCount, nIndex;
BOOL bSetIPR = FALSE;
PBYTE pData;
unsigned int lastPacketLen = 0;
unsigned int word_count, byte_count;
unsigned long tx_word; //*pTxWord,
//unsigned char *pTxByte;
volatile BYTE *pEP0FIFO = NULL;
BYTE ch1, ch2, ch3;
pEP0FIFO = (volatile BYTE *) &(UDC_DR_0( pHWHead ));
// Check for premature status stage.
if(UDC_CSR0( pHWHead) & XLLP_UDC_UDCCSR0_OPR && !(UDC_CSR0(pHWHead) & XLLP_UDC_UDCCSR0_SA)) {
// Premature status stage. Flush the xmit fifo and return back to
// a wait for setup state.
UDCTrace( pHWHead, UDCT_PRE_STATUS, UDC_CSR0( pHWHead ));
// Clear the xmit fifo
UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_FTF );
// Clear the OPR bit
UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_OPR );
// Go back to waiting for setup.
UDC_STATE( pHWHead ) = WAIT_FOR_SETUP;
return;
}
// Is there a stall?
if( UDC_CSR0( pHWHead ) & XLLP_UDC_UDCCSR0_SST ) {
// Stall has been detected. Clear the condition and go back to wait for setup.
UDCTrace( pHWHead, UDCT_STALL, UDC_CSR0( pHWHead ));
UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_SST );
UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_FTF );
UDC_STATE( pHWHead ) = WAIT_FOR_SETUP;
return;
}
// NKDbgPrintfW(TEXT("Send data Req:%d Len:%d Index:%d UDC_state:%d\r\n"),
// pHWHead->nXmitReq, pHWHead->nXmitLength, pHWHead->nXmitIndex, UDC_STATE(pHWHead));
// The ParseSetup has already setup the structure to determine how much
// data to send. Determine if this is the last data packet.
if( pHWHead->nXmitLength < EP0Len ) {
// UDC_STATE( pHWHead ) = WAIT_FOR_OUT_STATUS;
nXferCount = pHWHead->nXmitLength;
// If transmitting less than maxpacket, set IPR.
bSetIPR = TRUE;
UDCTrace( pHWHead, UDCT_UDCCS0_STATE, UDC_CSR0( pHWHead ));
} else {
// More data to send
UDC_STATE( pHWHead ) = DATA_STATE_XMIT;
nXferCount = EP0Len;
}
// Get the current index from the state structure and shove the data
// into the FIFO's. Adjust the remaining length
nIndex = pHWHead->nXmitIndex;
pData = pHWHead->pXmitData;
pHWHead->nXmitIndex = nIndex+nXferCount;
pHWHead->nXmitLength -= nXferCount;
UDCTrace( pHWHead, UDCT_SEND_DATA, nXferCount );
//
// Write to the FIFO directly to send the bytes.
//
lastPacketLen = nXferCount;
word_count = lastPacketLen/4;
byte_count = lastPacketLen%4;
pData = pHWHead->pXmitData + nIndex;
nIndex = 0; // bpc stuff. since pData already has nIndex added to it, reset nIndex back to 0.
// bpc stuff. that way, the single byte transmissions start off at the right place,
// bpc stuff. since the full word transmissions update nIndex as they go.
if(word_count)
{
while (word_count--)
{
//tx_word = (((pData[nIndex+3])<<24) | ((pData[nIndex+2])<<16) | ((pData[nIndex+1])<<8) | (pData[nIndex]));
tx_word = (((pData[3])<<24) | ((pData[2])<<16) | ((pData[1])<<8) | (pData[0]));
UDC_DR_0( pHWHead ) = tx_word;
pData +=4;
nIndex +=4;
}
pData = pHWHead->pXmitData;
}
if(byte_count)
{
if(byte_count==1)
{
ch1 = pData[nIndex++];//*pTxByte++;
*(pEP0FIFO) = ch1;
}
else if (byte_count==2)
{
ch1 = pData[nIndex++]; //*pTxByte++;
ch2 = pData[nIndex++]; //*pTxByte++;
*(pEP0FIFO) = ch1;
*(pEP0FIFO) = ch2;
}
else if (byte_count==3)
{
ch1 = pData[nIndex++]; //*pTxByte++;
ch2 = pData[nIndex++]; //*pTxByte++;
ch3 = pData[nIndex++]; //*pTxByte++;
*(pEP0FIFO) = ch1;
*(pEP0FIFO) = ch2;
*(pEP0FIFO) = ch3;
}
}
// If we are transmitting less than maxpacket, IPR is set.
if( bSetIPR ) {
UDCTrace( pHWHead, UDCT_UDCCS0, XLLP_UDC_UDCCSR0_IPR );
UDC_CSR0_MWRITE( UDC_CSR0(pHWHead), XLLP_UDC_UDCCSR0_IPR );
}
// bpc:
// switch states to OUT STATUS (or Handshake) WAIT
// when the transmission is done.
// the transmission is done when:
// the transmitted length equals the requested length, or
// there are no more bytes to send. (in this case, a 0 length
// packet would have just been transmitted.)
if( pHWHead->nXmitIndex == pHWHead->nXmitReq )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -