📄 bvd_udc_hw.c
字号:
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);
// if ((pData[0] == cEvtChar) || (pData[1] == cEvtChar) || (pData[2] == cEvtChar))
// fRXFlag = TRUE ;
}
pData+= byte_count;
RxPacketLen += byte_count;
RxPacketIndex += byte_count;
byte_count -= byte_count;
}
// Clear the PC bit
if( UDC_CSR_B( pHWHead ) & XLLP_UDC_UDCCSR_PC )
{
UDCCSR_MWRITE(UDC_CSR_B( pHWHead), XLLP_UDC_UDCCSR_PC);
// Clear Interrupt
UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_0);
}
dw_udc_csr_b = UDC_CSR_B( pHWHead );
// Clear the TRN bit
if(dw_udc_csr_b & XLLP_UDC_UDCCSR_TRN )
{
UDCCSR_MWRITE( UDC_CSR_B(pHWHead), XLLP_UDC_UDCCSR_TRN );
//UDCTrace( pHWHead, UDCT_UDC_CSR_A, UDC_CSR_A( pHWHead ));
}
if (buflen >= bytes_to_read)
{
//memcpy(pRxBuffer, RxPacket, RxPacketLen );
pRxBuffer += RxPacketLen;
(*pBufflen) += RxPacketLen;
bytes_to_read -=RxPacketLen;
buflen-= RxPacketLen;
RxPacketIndex =0;
RxPacketLen = 0;
}
else if (buflen)
{
//RETAILMSG(1, (TEXT("***RX: RxPktLen:%X buflen%X\r\n"), RxPacketLen, buflen));
memcpy(pRxBuffer, RxPacket, buflen );
pRxBuffer += buflen;
(*pBufflen) += buflen;
bytes_to_read -=buflen;
RxPacketLen -= buflen;
RxPacketIndex += buflen;
buflen-= buflen;
//NKDbgPrintfW(TEXT("***RX: RxPktLen:%X buflen%X\r\n"), RxPacketLen, buflen);
}
else
{
//NKDbgPrintfW(TEXT("***RX: Buffer FULL RxPacketLen:%X buflen%X\r\n"), RxPacketLen, buflen);
}
}
}while(dw_udc_csr_b & XLLP_UDC_UDCCSR_PC && buflen);
}
/*
// If we didn't read the whole buffer we need to come back. Leave with
// the interrupt still enabled so the MDD will recall.
if ((UDC_CSR_B( pHWHead) & XLLP_UDC_UDCCSR_BNE_BNF ) || word_count || byte_count)
{
DEBUGMSG( ZONE_USB, (TEXT("RNE")));
//RETAILMSG( 1, (TEXT("\r\nRx: ****RNE*****bytes_to_read:%X Buflen:%X\r\n"), bytes_to_read, buflen));
UDCTrace( pHWHead, UDCT_RX_INTR_DONE, UDC_CSR_B( pHWHead ));
//UDCTrace( pHWHead, UDCT_UDC_RX_BUF_EMPTY, (bytes_to_read - word_count*4 - byte_count) );
//return fRXFlag;
}
*/
//UDCTrace( pHWHead, UDCT_RX_INTR_DONE, UDC_CSR_B( pHWHead ));
// To do: Deal with EPB FIFO error intr
//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_1);
// Clear Interrupt
//UISR_IR2_CLR (pHWHead->pUDCRegs->uisr0);
//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRB_0);
//UDCTrace( pHWHead, UDCT_INTR, UDC_ISR0(pHWHead) );
UDCTrace( pHWHead, UDCT_RX_DATA, *pBufflen );
//RETAILMSG( 1, (TEXT("Rx Data:%d UDC_CSR_B:%X UDC_ISR0:%X\r\n"),*pBufflen, UDC_CSR_B( pHWHead), UDC_ISR0(pHWHead)));
//g_pBLReg->hex_led = 0xFFFFA00A;
//if ( LineEvents )
//{
// RETAILMSG(1, (TEXT("***************RX: Calling EvaluateEvent...%X\r\n"), buflen));
// pHWHead->EventCallback( pHWHead->pMddHead, LineEvents );
//}
return fRXFlag;
}
/*
* SA_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 SA_USB_TxIntHandler(PSER_INFO pHWHead,
PUCHAR pTxBuffer,
ULONG *pBuffLen)
{
unsigned int len = *pBuffLen;
int skip = 0;
static UCHAR lastPacket[EP1Len];
static unsigned int lastPacketLen = 0;
static unsigned int ZLP = 0;
BOOL bSendShortPacket = FALSE;
DWORD dw_udc_csr_a; //dw_udc_cr_a
unsigned int word_count, byte_count;
//unsigned long *pTxWord;
//unsigned char *pTxByte;
PBYTE pData;
int nIndex;
unsigned long tx_word;
volatile BYTE *pEP_A_FIFO;
//BYTE ch1, ch2, ch3;
pEP_A_FIFO = (volatile BYTE *) &(UDC_DR_A( pHWHead ));
//*pBuffLen = 0;
/*
* We are called under a few different conditions:
* New packet - called directly and potentially while we are still sending
* an old packet. We detect this by checking lastPacketLen and skipping
* out if it is still set.
* Next packet - called by interrupt handler thread when TPC interrupt
* is delivered. We check the TPE bit to see if we need to retransmit. If
* so we ignore the caller's arguments, resend the packet and indicate we
* sent no bytes so we'll get called back. The caller will either send a
* NULL pointer if no more data to send or a non NULL pointer for the
* next packet. If NULL we clear the interrupt and skip out. Otherwise we
* queue the next packet.
*/
//g_pBLReg->hex_led = 0xFFFFB001;
dw_udc_csr_a = UDC_CSR_A( pHWHead );
//dw_udc_cr_a = ENDPOINT_A(pHWHead) ;
//RETAILMSG(1, (TEXT("TX: UDC_CR_A=%X , UDC_CSR_A=%X \r\n"), dw_udc_cr_a , dw_udc_csr_a ));
UDCTrace( pHWHead, UDCT_TX_DATA, len );
UDCTrace( pHWHead, UDCT_UDC_CSR_A, dw_udc_csr_a );
//DEBUGMSG(ZONE_WRITE, (TEXT("TX Buff Len = %d, UDC_CSR_A=%X \r\n"), len, dw_udc_csr_a ));
//RETAILMSG(1, (TEXT("TX: %d\r\n"),len));
// To do: Deal with EPA FIFO error intr
// Deal with EPB FIFO error intr
if (UDC_ISR0(pHWHead) & XLLP_UDC_UDCISR0_IRA_1)
{
//NKDbgPrintfW(TEXT("****!!! EPA FIFO error\r\n"));
UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_1);
}
// Clear Interrupt
//A.K.
// UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
// Clear any underrun conditions.
//
// TRN Usage Note:
// TRN is just a status bit for Bulverde.
// It shows that the host is asking for data
// faster than we can give it.
//
if( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_PC )
{
// Clear the TPC
UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );
if( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_TRN )
{
UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
}
}
//A.K.
if ((! *pBuffLen ) && (lastPacketLen == 64))
{
UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP));
// Clear the TPC
UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );
// Clear the interrupt (must be done after clearing TPC
UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
lastPacketLen = 0;
*pBuffLen = 0;
return;
}
//
// If no bytes to send we're done. Interrupt has been cleared.
//
if ((! *pBuffLen ) && !ZLP )
{
// Clear the TPC
UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_PC );
// Clear the interrupt (must be done after clearing TPC
UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
//UDCTrace( pHWHead, UDCT_TPC, len );
UDCTrace( pHWHead, UDCT_XMIT_DONE, UDC_CSR_A(pHWHead) );
//g_pBLReg->hex_led = 0xFFFFB00C;
return;
}
*pBuffLen = 0;
do
{
// We are sending a new packet(pTxBuffer).
//
if (len || ZLP ) //(pTxBuffer || ZLP )
{
lastPacketLen = min(EP1Len,len);
// Check if need to set the TSP bit.
if( lastPacketLen < EP1Len )
bSendShortPacket = TRUE;
/*
if ((UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_FS) == 0)
{
lastPacketLen = 0;
bSendShortPacket = FALSE;
UDCTrace( pHWHead, UDCT_XMIT_DONE, UDC_CSR_A(pHWHead) );
//RETAILMSG( 1, (TEXT("**************Tx FIFO full. Data Done:%X UDC_CSR_A:%X UDC_ISR0:%X\r\n"),
// *pBuffLen, UDC_CSR_A( pHWHead), UDC_ISR0(pHWHead)));
// Clear the interrupt (must be done after clearing TPC
//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
//return;
}
*/
if (lastPacketLen)
{
//memcpy( lastPacket, pTxBuffer, lastPacketLen );
udcStats.goodWrPacketCount++;
*pBuffLen += lastPacketLen;
}
}
DEBUGMSG( ZONE_WRITE,(TEXT("TX: lastPacketLen = %d, bSendShortPacket=%d\r\n"), lastPacketLen, bSendShortPacket ));
UDCTrace( pHWHead, UDCT_EP1_XMIT, lastPacketLen );
UDCTrace( pHWHead, UDCT_EP1_XMIT, bSendShortPacket );
//
// Write to the FIFO directly to send the bytes.
//
word_count = lastPacketLen/4;
byte_count = lastPacketLen%4;
pData = pTxBuffer; //lastPacket
nIndex=0;
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_A( pHWHead ) = tx_word;
//RETAILMSG( 1, (TEXT("Tx: %x %x %x %x\r\n"), pData[0], pData[1], pData[2], pData[3]));
pData +=4;
nIndex +=4;
}
//pData = pTxBuffer; //lastPacket
}
//pTxByte = (unsigned char *) (pData + (word_count*4)); //word_count = 0 always
//while (byte_count--)
//{
// ch1 = pData[nIndex++];//*pTxByte++;
// *(pEP_A_FIFO) = ch1;
//}
if(byte_count==1)
{
*(pEP_A_FIFO) = pData[0];
pData++;
nIndex++;
}
else if (byte_count==2)
{
*(pEP_A_FIFO) = pData[0];
*(pEP_A_FIFO) = pData[1];
nIndex+=2;
pData+=2;
}
else if (byte_count==3)
{
*(pEP_A_FIFO) = pData[0];
*(pEP_A_FIFO) = pData[1];
*(pEP_A_FIFO) = pData[2];
nIndex+=3;
pData+=3;
}
// Set the TSP bit.
if( bSendShortPacket)
{
//UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP | XLLP_UDC_UDCCSR_PC) );
UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , (XLLP_UDC_UDCCSR_SP));
//if (ZLP)
//{
// ZLP = 0;
// RETAILMSG( 1, (TEXT("Tx: Clearing ZLP\r\n")));
//}
}
//A.K.
dw_udc_csr_a = UDC_CSR_A( pHWHead );
//
// Clear the interrupt
if ( UDC_CSR_A( pHWHead ) & XLLP_UDC_UDCCSR_PC )
{
UDCCSR_MWRITE( UDC_CSR_A(pHWHead) , XLLP_UDC_UDCCSR_PC );
//A.K. //Clear TRN bit
if(dw_udc_csr_a & XLLP_UDC_UDCCSR_TRN )
{
UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
}
//
UDCTrace( pHWHead, UDCT_UDC_CSR_A, UDC_CSR_A( pHWHead ));
// Clear the interrupt (must be done after clearing PC
// UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
}
// dw_udc_csr_a = UDC_CSR_A( pHWHead );
//Clear TRN bit
// if(dw_udc_csr_a & XLLP_UDC_UDCCSR_TRN )
// {
// UDCCSR_MWRITE( UDC_CSR_A(pHWHead), XLLP_UDC_UDCCSR_TRN );
// }
pTxBuffer += lastPacketLen;
len -= lastPacketLen;
// }while(dw_udc_csr_a & XLLP_UDC_UDCCSR_FS && len);
}while((dw_udc_csr_a & (XLLP_UDC_UDCCSR_BNE_BNF | XLLP_UDC_UDCCSR_FS)) && len);
//A.K.
// Clear the interrupt (must be done after clearing PC
UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
UDCTrace( pHWHead, UDCT_XMIT_DONE, dw_udc_csr_a); //UDC_CSR_A(pHWHead) );
//RETAILMSG( 1, (TEXT("Tx Data:%d UDC_CSR_A:%X UDC_ISR0:%X \r\n"),lastPacketLen, UDC_CSR_A( pHWHead), UDC_ISR0(pHWHead)));
//
// Clear the interrupt
// This must be done last, after clearing TPC
//
// To do: Deal with EPB FIFO error intr
// UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_1);
// Clear Interrupt
//UISR_IR1_CLR (pHWHead->pUDCRegs->uisr0);
//UDC_ISR0_CLEAR_ENDPOINT_INTR( UDC_ISR0(pHWHead), XLLP_UDC_UDCISR0_IRA_0);
//UDCTrace( pHWHead, UDCT_UDC_ISR0, UDC_ISR0(pHWHead) );
//g_pBLReg->hex_led = 0xFFFFB00D;
return;
}
/*
* SA_USB_PowerOff
*
*
*/
void SA_USB_PowerOff(
PSER_INFO pHWHead
)
{
UDCCR_UDE_DISABLE( UDC_CR(pHWHead) );
}
/*
* SA_USB_PowerOn
*
*
*/
void SA_USB_PowerOn(
PSER_INFO pHWHead
)
{
unsigned long udc_crA_val, udc_crB_val ;
//Configuring Endpoint A
//BULK IN with max pkt size 64
udc_crA_val = ( XLLP_UDC_UDCCRZ_EE | MAX_PKT_BULK_64 |
EP_DIRECTION_IN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -