?? hardware_8041_int.c
字號:
}
if ( length > EMAC_BLOCK_SIZE )
{
templen = length;
for ( i = 0; (uint32)(length/EMAC_BLOCK_SIZE) + 1; i++ )
{
templen = length - EMAC_BLOCK_SIZE;
/* two words at a time, packet and control */
tx_desc_addr = (uint32 *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
if ( templen % EMAC_BLOCK_SIZE )
{
/* full block */
*tx_desc_addr = (uint32)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (uint32)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1));
TxProduceIndex++;
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now */
}
else
{
/* last fragment */
*tx_desc_addr = (uint32)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (uint32)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST | (templen -1) );
TxProduceIndex++; /* transmit now */
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now */
break;
}
}
}
else
{
tx_desc_addr = (uint32 *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
*tx_desc_addr = (uint32)(EMACBuf);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (uint32)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST | EMAC_TX_DESC_PAD| (length -1));
TxProduceIndex++; /* transmit now */
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex;
}
return ( TRUE );
}
/**********************************************************************
**函數原型: void Send_Packet(struct _pkst *TxdData)
**入口參數: struct _pkst *TxdData :指向要發送數據的結構指針
**
**出口參數: 無
**返 回 值: 無
**說 明: 發送數據包,以太網底層驅動程序,所有的數據發送都要通過該程序
************************************************************************/
void Send_Packet(struct _pkst *TxdData)//
{
struct _pkst *ExPtr;//
uint8 *TEPTR;
uint8 *rxptr;
uint16 ii,length=0,jj;
uint32 intstat;
length=length+TxdData->length;
ExPtr=TxdData->STPTR;
while(ExPtr!=NULL)//計算出要發送的數據的總長度
{
length=length+ExPtr->length;
ExPtr=ExPtr->STPTR;
}
ii=length;
rxptr = (uint8 *)EMAC_TX_BUFFER_ADDR;
TEPTR=TxdData->DAPTR;
for(ii=0;ii<TxdData->length;ii++)
{
*rxptr = *TEPTR;
rxptr++;
TEPTR++;
}
ExPtr=TxdData->STPTR;
while(ExPtr!=NULL)
{
TEPTR=ExPtr->DAPTR;
for(ii=0;ii<ExPtr->length;ii++)
{
*rxptr = *TEPTR;
rxptr++;
TEPTR++;
}
ExPtr=ExPtr->STPTR;
}
//如果少于60
ii=length;
if(length<60)
{
//如果數據長度<60字節,設置長度為60字節
ii=60;
}
rxptr = (uint8 *)EMAC_TX_BUFFER_ADDR;
EMACSend((uint32 *)rxptr,ii);
/***************************************/
//重發數據的處理
for(length=0;length<6;length++) //最多重發6次
{
for(jj=0;jj<1000;jj++)
{//檢查CR寄存器的txp位是否為低,為1說明正在發送,為0說明發完或出錯放棄
intstat = MAC_INTSTATUS;
intstat |= EINTSTA;
if ( intstat & EMAC_INT_TXDONE )
{
TxDoneCount++;
break;
}
}
if(intstat & EMAC_INT_TXDONE)//表示發送成功,判斷發送狀態寄存器TSR,決定是否出錯
{
MAC_INTCLEAR = 0x0f;//EMAC_INT_TXDONE;
EINTSTA &= 0xf0;
break;
}
EMACSend((uint32 *)rxptr,ii); //to sendpacket;
}
/**************************************/
//OS_EXIT_CRITICAL();
}
uint32 EMACReceiveFractions( uint32 StartIndex, uint32 EndIndex, uint32 * dataptr32 )
{
uint32 i, RxLength = 0;
uint32 RxSize;
uint32 *rx_status_addr,*rx_desc_addr,*rx_data_addr;
for ( i = StartIndex; i < EndIndex; i++ )
{
/* Get RX status, two words, status info. and status hash CRC. */
rx_status_addr = (uint32 *)(RX_STATUS_ADDR + StartIndex * 8);
rx_desc_addr = (uint32 *)(RX_DESCRIPTOR_ADDR + StartIndex * 8);
rx_data_addr = (uint32 *)(*rx_desc_addr);
RxSize = (*rx_status_addr & DESC_SIZE_MASK) - 1;
for(i=0;i<(RxSize+3)/4;i++)
dataptr32[i]=*rx_data_addr++;
/* two words at a time, packet and control */
CurrentRxPtr += EMAC_BLOCK_SIZE;
StartIndex++;
/* last fragment of a frame */
if ( *rx_status_addr & RX_DESC_STATUS_LAST )
{
/* set INT bit and RX packet size */
MAC_RXCONSUMEINDEX = StartIndex;
RxLength += RxSize;
break;
}
else /* In the middle of the frame, the RxSize should be EMAC_BLOCK_SIZE */
/* In the emac.h, the EMAC_BLOCK_SIZE has been set to the largest
ethernet packet length to simplify the process, so, it should not
come here in any case to deal with fragmentation. Otherwise,
fragmentation and repacking will be needed. */
{
/* set INT bit and maximum block size */
MAC_RXCONSUMEINDEX = StartIndex;
/* wait until the whole block is received, size is EMAC_BLOCK_SIZE. */
while ( (*rx_status_addr & DESC_SIZE_MASK) != (EMAC_BLOCK_SIZE - 1));
RxLength += RxSize;
}
}
return( RxLength );
}
/******************************************************************************
** Function name: EMACHandler
**
** Descriptions: EMAC interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void InitNic(uint8 num);
void EMACHandler (uint32 IntStatus)
{
//IENABLE; /* handles nested interrupt */
IntStatus = MAC_INTSTATUS;
IntStatus |= EINTSTA;
if ( IntStatus != 0 ) /* At least one interrupt */
{
if ( IntStatus & EMAC_INT_RXOVERRUN )
{
MAC_INTCLEAR = EMAC_INT_RXOVERRUN;
RXOverrunCount++;
//InitNic(0);
EMACRxDescriptorInit();
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_RXERROR )
{
MAC_INTCLEAR = EMAC_INT_RXERROR;
RXErrorCount++;
//InitNic(0);
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_RXFINISHED )
{
MAC_INTCLEAR = EMAC_INT_RXFINISHED;
RxFinishedCount++;
/* Below should never happen or RX is seriously wrong */
//while ( MAC_RXPRODUCEINDEX != (MAC_RXCONSUMEINDEX - 1) );
}
if ( IntStatus & EMAC_INT_TXUNDERRUN )
{
MAC_INTCLEAR = EMAC_INT_TXUNDERRUN;
TXUnderrunCount++;
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_TXERROR )
{
MAC_INTCLEAR = EMAC_INT_TXERROR;
TXErrorCount++;
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_TXFINISHED )
{
MAC_INTCLEAR = EMAC_INT_TXFINISHED;
TxFinishedCount++;
}
EINTSTA &= 0x88;
}
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
/**********************************************************************
**函數原型: unsigned char * Rec_Packet()
**入口參數:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -