📄 initial.c.bak
字号:
#include "initial.h"
EMAC_Config g_emacConfig;
// Declare packet queues
extern PKTQ FreeQueue; // Free packets for RX or Tx
extern PKTQ RxQueue; // Received packets
// Declare some local status variables
extern Handle hEMAC; // Handle to our EMAC instance
extern volatile uint LinkStatus; /* Current link status */
extern volatile uint LocalTicks; /* Current time in 100ms ticks */
void Initial()
{
Uint32 i;
g_emacConfig.ModeFlags = EMAC_CONFIG_MODEFLG_CHPRIORITY;
g_emacConfig.MdioModeFlags = MDIO_MODEFLG_AUTONEG;
g_emacConfig.TxChannels = 1;
for( i=0; i<6; i++ )
{
g_emacConfig.MacAddr[i] = i;
}
g_emacConfig.RxMaxPktPool = 8;
g_emacConfig.pfcbGetPacket = &GetPacket;
g_emacConfig.pfcbFreePacket = &FreePacket;
g_emacConfig.pfcbRxPacket = &RxPacket;
g_emacConfig.pfcbStatus = &StatusUpdate;
g_emacConfig.pfcbStatistics = &StatisticsUpdate;
InterruptInit();
EMACControlModuleInit();
MDIOInit();
EMACModuleInit();
return;
}
void EMACControlModuleInit()
{
Uint32 tmpVal;
Uint32 i;
// Globally disable EMAC/MDIO interrupts in wrapper and
// put both EMAC and MDIO modules into reset
EMAC_RSET( EWCTL, EMAC_FMKS( EWCTL, INTEN, DISABLE ) |
EMAC_FMKS( EWCTL, EMACRST, YES ) |
EMAC_FMKS( EWCTL, MDIORST, YES ) );
// Wait ablout 100 cycles
for( i=0; i<5; i++ )
{
tmpVal = EMAC_RGET( EWCTL );
}
// Leave EMAC/MDIO interrupts disabled and take both
// EMAC and MDIO modules out of reset
EMAC_RSET( EWCTL, EMAC_FMKS( EWCTL, INTEN, DISABLE ) |
EMAC_FMKS( EWCTL, EMACRST, NO ) |
EMAC_FMKS( EWCTL, MDIORST, NO ) );
// Wait ablout 100 cycles
for( i=0; i<5; i++ )
{
tmpVal = EMAC_RGET( EWCTL );
}
// Set EMAC Priority to "2" ,allocation regs "3"
EMAC_RSET( EWTRCTRL, 0x23 );
// Set Interrupt Timer Count (CPUclk/4)
EMAC_RSET( EWINTTCNT, 1500 );
// Enable global interrupt in wrapper
EMAC_FSETS( EWCTL, INTEN, ENABLE );
return;
}
void MDIOInit()
{
#define PCLK 5
MDIO_RSET( CONTROL, MDIO_FMKS( CONTROL, ENABLE, YES ) |
MDIO_FMK( CONTROL, CLKDIV, PCLK ) |
MDIO_FMKS( CONTROL, PREAMBLE, DISABLED));
return;
}
void EMACModuleInit()
{
volatile Uint32 *pRegAddr;
Uint32 i;
Uint32 tmpVal = 0;
//Disable transmit,receive and clear MACCCONTROL
EMAC_FSETS( TXCONTROL, TXEN, DISABLE );
EMAC_FSETS( RXCONTROL, RXEN, DISABLE );
EMAC_RSET( MACCONTROL, 0 );
// MUST manually init TXnHDPs to NULL
pRegAddr = EMAC_ADDR( TX0HDP );
for( i=0; i<8; i++ )
{
*pRegAddr++ = 0;
}
// MUST manually init RXnHDPs to NULL
pRegAddr = EMAC_ADDR( RX0HDP );
for( i=0; i<8; i++ )
{
*pRegAddr++ = 0;
}
// 初始化统计寄存器
pRegAddr = EMAC_ADDR( RXGOODFRAMES );
for( i=0; i<36; i++ )
{
*pRegAddr++ = 0;
}
//初始化MAC地址 00 01 02 03 04 05
//每个通道都初始化
pRegAddr = EMAC_ADDR( MACADDRL0 );
for( i=0; i<8; i++ )
{
*pRegAddr++ = g_emacConfig.MacAddr[5];
}
EMAC_RSET( MACADDRM, g_emacConfig.MacAddr[4] );
for( i=3; i<0; i--)
{
tmpVal = ( tmpVal<<8 ) | g_emacConfig.MacAddr[i];
}
EMAC_RSET( MACADDRH, tmpVal );
// Buffer offset always be zero
EMAC_RSET( RXBUFFEROFFSET, 0 );
// Clear Unicast receive on channel 0-7
EMAC_RSET( RXUNICASTCLEAR, 0xFF );
// Reset receive MBP enable register
EMAC_RSET( RXMBPENABLE, 0 );
// Enable transmit channel and receive channel interrupts
EMAC_RSET( TXINTMASKCLEAR, 0xFF );
EMAC_RSET( TXINTMASKSET , 1<<0 );
EMAC_RSET( RXINTMASKCLEAR, 0xFF );
EMAC_RSET( RXINTMASKSET , 1<<0 );
// Enable transmit
EMAC_FSETS( TXCONTROL, TXEN, ENABLE );
// Enable receive
EMAC_FSETS( RXCONTROL, RXEN, ENABLE );
//Enable global interrupt in control module
EMAC_FSETS( EWCTL, INTEN, ENABLE );
return;
}
void InterruptInit()
{
IRQ_globalDisable();
IRQ_setVecs(vectors);
IRQ_map(IRQ_EVT_MACINT, 6);
IRQ_resetAll();
IRQ_nmiEnable();
IRQ_enable(IRQ_EVT_MACINT); //使能EMAC中断
IRQ_globalEnable();
return;
}
/*
*----------GetPacket - Get empty packet for RX-------------
*
* This function is called from the EMAC module to get an
* empty packet buffer. It returns a packet buffer to the
* EMAC or returns NULL if there are no buffers available.
*/
EMAC_Pkt *GetPacket( Handle hApplication )
{
EMAC_Pkt *pPkt;
/* Verify if handle came back OK. It is not used in this example */
if( (Uint32)hApplication != 0x12345678 )
{
printf("GetPacket(): Bad App Handle!\n");
return(0);
}
/* Pop a packet off our local free queue */
pPkt = pqPop(&FreeQueue);
if( pPkt )
{
//Tell the EMAC what offset to use by setting the DataOffset field
// in the packet.
pPkt->DataOffset = 0;
}
return( pPkt );
}
/*
* FreePacket - Free packet that originated from TX or GetPacket().
*
* This function is called from the EMAC module to free a
* packet buffer after a TX operation (or RX in the case of
* a RX shutdown).
*
*/
void FreePacket( Handle hApplication, EMAC_Pkt *pPKT )
{
/* Verify if handle came back OK. It is not used in this example */
if( (Uint32)hApplication != 0x12345678 )
{
printf("FreePacket(): Bad App Handle!\n");
return;
}
pqPush( &FreeQueue, pPKT );
}
/*
* RxPacket - Reveived packet from the Network.
*
* This function is called by the EMAC to indicate a receive.
* It just pushes the packet our receive queue.
*
* This function returns a free packet to replace the RX packet on
* the EMAC queue. If there are no free packets available, it
* returns NULL.
*/
EMAC_Pkt *RxPacket( Handle hApplication, EMAC_Pkt *pPKT )
{
/* Verify if handle came back OK. It is not used in this example */
if( (Uint32)hApplication != 0x12345678 )
{
printf("RxPacket(): Bad App Handle!\n");
return(0);
}
/* Push this packet onto local receive queue */
pqPush( &RxQueue, pPKT );
/* Return a free packet to replace the one which was given */
return( GetPacket(hApplication) );
}
char *LinkStr[] = { "No Link", "10Mb/s Half Duplex", "10Mb/s Full Duplex",
"100Mb/s Half Duplex", "100Mb/s Full Duplex" };
// StatusUpdate - The EMAC or MDIO status has changed
void StatusUpdate( Handle hApplication )
{
uint retval;
EMAC_Status status;
/* Verify if handle came back OK. It is not used in this example */
if( (Uint32)hApplication != 0x12345678 )
{
printf("StatusUpdate(): Bad App Handle!\n");
return;
}
/*
* The status update function is called for several reasons, including
* LINK change events and EMAC errors. Get the current status and print
* it out. Don't start sending packets until there is a good link.
*
* NOTE: Call back into the EMAC is used without any reentrancy concerns.
* This because we are a callback function currently that was called
* from EMAC. Thus the reentrancy protection is still active!
*/
retval = EMAC_getStatus( hEMAC, &status );
printf("\ngetStatus() returned %d\n",retval);
LinkStatus = status.MdioLinkStatus;
if( !LinkStatus )
printf("Link Status: %s\n",LinkStr[LinkStatus]);
else if( LinkStatus <= 4 )
printf("Link Status : %s on PHY number %d\n",
LinkStr[LinkStatus],status.PhyDev);
printf("Packets Held : %d-RX %d-TX\n",
status.RxPktHeld, status.TxPktHeld);
if( status.FatalError )
printf("Fatal Error : %d\n",status.FatalError);
}
// StatisticsUpdate - The EMAC statistics are in danger of overflow
void StatisticsUpdate( Handle hApplication )
{
/* Verify if handle came back OK. It is not used in this example */
if( (Uint32)hApplication != 0x12345678 )
{
printf("StatisticsUpdate(): Bad App Handle!\n");
return;
}
/*
* Here call the EMAC_getStatistics() function and pass them to whoever
* needing statistics information. This example doesn't have anything to
* do with it so nothing is called here.
*/
printf("StatisticsUpdate() Called\n");
}
/*
*----------pqPop()------------
*
* Pop a desc buffer off a queue
*/
EMAC_Pkt *pqPop( PKTQ *pq )
{
EMAC_Pkt *pPktHdr;
IRQ_disable( IRQ_EVT_MACINT );
pPktHdr = pq->pHead;
if( pPktHdr )
{
pq->pHead = pPktHdr->pNext;
pq->Count--;
}
pPktHdr->pPrev = pPktHdr->pNext = 0;
IRQ_enable( IRQ_EVT_MACINT );
return( pPktHdr );
}
/*
*--------pqPush()-------------
*
* Push a desc buffer onto a queue
*/
void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr )
{
IRQ_disable( IRQ_EVT_MACINT );
pPktHdr->pNext = 0;
if( !pq->pHead )
{
// Queue is empty - Initialize it with this one packet
pq->pHead = pPktHdr;
pq->pTail = pPktHdr;
}
else
{
// Queue is not empty - Push onto END
pq->pTail->pNext = pPktHdr;
pq->pTail = pPktHdr;
}
pq->Count++;
IRQ_enable( IRQ_EVT_MACINT );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -