/***********************************************************************
emactest.c main program
***********************************************************************/
// Header section
#include <string.h>
#include "LPC23xx.h" /* LPC23xx definitions */
#include "type.h"
#include "crc32.h"
#include "emac.h"
#define TX_PACKET_SIZE 43
/* Packet generation function */
void PacketGen( BYTE *txptr )
{
int i;
DWORD crcValue;
DWORD BodyLength = TX_PACKET_SIZE - 38;
/* Dest(PC) MAC address 00-18-7D-03-23-17 */
*(txptr+0) = 0x17;
*(txptr+1) = 0x23;
*(txptr+2) = 0x03;
*(txptr+3) = 0x7D;
*(txptr+4) = 0x18;
*(txptr+5) = 0x00;
/* Source(ARM LPC2468) MAC address 00-1A-F1-01-06-89 */
*(txptr+6) = 0x89;
*(txptr+7) = 0x06;
*(txptr+8) = 0x01;
*(txptr+9) = 0xF1;
*(txptr+10) = 0x1A;
*(txptr+11) = 0x00;
/* Type VLAN or IP - 0x0800 */
*(txptr+12) = 0x08;
*(txptr+13) = 0x00;
*(txptr+14) = 0x54; // IPv4 and IP header length=5 (5*32bit )
*(txptr+15) = 0xF0; //Type of service 1111 0000 default value
/* Total Length 0x0030 = 48 */
*(txptr+16) = 0x30;
*(txptr+17) = 0x00;
/* Identifier default value which is incremented automatically*/
*(txptr+18) = 0x00;
*(txptr+19) = 0x48;
/* flags & fragment offset*/
*(txptr+20) = 0x00;
*(txptr+21) = 0x00;
/*Time To Live = a non zero value */
*(txptr+22) = 0x80;
/* protocol type UDP=17(0x11) */
*(txptr+23) = 0x11;
/* check sum */
*(txptr+24) = 0x00;
*(txptr+25) = 0x00;
/* Source IP 192.100.100.101 */
*(txptr+26) = 0x65;
*(txptr+27) = 0x64;
*(txptr+28) = 0x64;
*(txptr+29) = 0xC0;
/* destination IP 192.100.100.102 */
*(txptr+30) = 0x66;
*(txptr+31) = 0x64;
*(txptr+32) = 0x64;
*(txptr+33) = 0xC0;
/* source port 4000 (0FA0) other than 1-1023 standard ports*/
*(txptr+34) = 0xA0;
*(txptr+35) = 0x0F;
/* dest port 6000 (1770) */
*(txptr+36) = 0x70;
*(txptr+37) = 0x17;
/* UDP total length 48 (0030H) */
*(txptr+38) = 0x30;
*(txptr+39)=0x00;
/* Pay load or data here example 55 55 55 55 is sent */
for ( i=0; i < BodyLength; i++ )
{
*(txptr+i+39) = 0x55;
}
/* calculate CRC */
crcValue = crc32_bfr( txptr, TX_PACKET_SIZE );
/* append CRC to packet */
*(txptr+TX_PACKET_SIZE) = (0xff & crcValue);
*(txptr+TX_PACKET_SIZE+1) = 0xff & (crcValue >> 8 );
*(txptr+TX_PACKET_SIZE+2) = 0xff & (crcValue >> 16);
*(txptr+TX_PACKET_SIZE+3) = 0xff & (crcValue >> 24);
return;
}
/* Main packet buffer creation module */
void AllPacketGen ( void )
{
DWORD i;
BYTE *txptr;
txptr = (BYTE *)EMAC_TX_BUFFER_ADDR;
for ( i = 0; i < EMAC_TX_BLOCK_NUM; i++ )
{
PacketGen( txptr );
txptr += EMAC_BLOCK_SIZE;
}
return;
}
/* MAIN function */
int main (void)
{
BYTE *txptr;
DWORD i = 0;
/* Initialize Ethernet – function in emac.c */
EMACInit();
/* Generate Packet */
AllPacketGen();
/*Enable Tranmission */
EMAC_TxEnable();
/* continous loop */
while ( 1 )
{
/* load txptr with buffer address */
txptr = (BYTE *)EMAC_TX_BUFFER_ADDR;
/* transmission process with Txdescriptors */
for ( i = 0; i < EMAC_TX_BLOCK_NUM; i++ )
{
/* Packet sender in emac.c with descriptor arrays */
EMACSend( (DWORD *)txptr, TX_PACKET_SIZE + 4 );
/* wait until transmit done is SET in TSV0 registor * /
while(MAC_TSV0 & 0x00000008 !=0);
/* update buffer to next location */
txptr += EMAC_BLOCK_SIZE;
}
}
return 0;
}
/***********************************************************************
End of emactest.c file
***********************************************************************/
/***********************************************************************
emac.c program
***********************************************************************/
#include "LPC23xx.h" /* LPC23xx definitions */
#include "type.h"
#include "target.h"
#include "irq.h"
#include "emac.h"
void EMAC_TxEnable( void )
{
MAC_COMMAND |= 0x02;
return;
}
void EMAC_TxDisable( void )
{
MAC_COMMAND &= ~0x02;
return;
}
void EMAC_RxEnable( void )
{
MAC_COMMAND |= 0x01;
MAC_MAC1 |= 0x01;
return;
}
void EMAC_RxDisable( void )
{
MAC_COMMAND &= ~0x01;
MAC_MAC1 &= ~0x01;
return;
}
void WritePHY( DWORD PHYReg, DWORD PHYData )
{
MAC_MCMD = 0x0000; /* write command */
MAC_MADR = (0x0000 << 8)| PHYReg; /* physical address */
MAC_MWTD = PHYData;
while ( MAC_MIND != 0 );
return;
}
DWORD ReadPHY( DWORD PHYReg )
{
MAC_MCMD = 0x0001; /* read command */
MAC_MADR = (0x0000 << 8) | PHYReg;
while ( (MAC_MIND & 0x05) != 0 );
MAC_MCMD = 0x0000;
return( MAC_MRDD );
}
void EMACTxDescriptorInit( void )
{
DWORD i;
DWORD *tx_desc_addr, *tx_status_addr;
/* Base addr of tx descriptor array */
MAC_TXDESCRIPTOR = TX_DESCRIPTOR_ADDR;
/* Base addr of tx status */
MAC_TXSTATUS = TX_STATUS_ADDR;
/* number of tx descriptors, 16 */
MAC_TXDESCRIPTORNUM = EMAC_TX_DESCRIPTOR_COUNT - 1;
for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
{
/* two words at a time, packet and control */
tx_desc_addr = (DWORD *)(TX_DESCRIPTOR_ADDR + i * 8);
*tx_desc_addr = (DWORD)(EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
/* set size only */
*(tx_desc_addr+1) = (DWORD)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - ));
}
for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
{
/* TX status, one word only, status info. */
tx_status_addr = (DWORD *)(TX_STATUS_ADDR + i * 4);
/* initially, set status info to 0 */
*tx_status_addr = (DWORD)0;
/* TX descriptors point to zero *
}
MAC_TXPRODUCEINDEX = 0x0;
return;
}
DWORD EMACInit( void )
{
DWORD regVal,regv,tout,id1,id2;
DWORD i;
PCONP |= 0x40000000;
for ( i = 0; i < 0x100; i++ ); /* short delay */
regVal = MAC_MODULEID;
if ( regVal == PHILIPS_EMAC_MODULE_ID )
{
PINSEL2 = 0x50151105; /* selects P1[0,1,4,6,8,9,10,14,15] */
}
else
{
PINSEL2 = 0x50150105; /* selects P1[0,1,4,8,9,10,14,15] */
}
PINSEL3 = 0x00000005; /* selects P1[17:16] */
// Reset all
MAC_MAC1 = 0x0000CF00; /* soft resets all MAC internal modules */
MAC_COMMAND = 0x0038; /* reset all datapaths and host registers */
for ( i = 0; i < 0x04; i++ ); /* short delay after reset */
MAC_MAC1 = 0x00000000; /* deassert all of the above soft resets in MAC1 */
EMAC_TxDisable();
EMAC_RxDisable();
/* Initialize MAC control registers. */
MAC_MAC1 = MAC1_PASS_ALL;
MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
MAC_MAXF = ETH_MAX_FLEN;
MAC_CLRT = CLRT_DEF;
MAC_IPGR = IPGR_DEF;
/* Enable Reduced MII interface. */
MAC_COMMAND = CR_RMII | CR_PASS_RUNT_FRM;
/* Reset Reduced MII Logic. */
MAC_SUPP = SUPP_RES_RMII;
for (tout = 100; tout; tout--); /* short delay */
MAC_SUPP = 0;
for ( i = 0; i < 0x100; i++ ); /* short delay */
WritePHY (PHY_BMCR, 0x8000); // reset harware
/* Wait for hardware reset to end. */
for (tout = 0; tout < 0x100000; tout++)
{
regv = ReadPHY (PHY_BMCR);
// value changed from 0x8000 to 0x8800 for EA board
if (!(regv & 0x8800))
{
/* Reset complete */
break;
}
}
/* Configure the PHY device */
/* Use autonegotiation about the link speed. */
WritePHY (PHY_BMCR, PHY_AUTO_NEG);
/* Wait to complete Auto_Negotiation. */
for (tout = 0; tout < 0x100000; tout++)
{
regv = ReadPHY (PHY_BMSR);
if (regv & 0x0020) {
/* Autonegotiation Complete. */
break;
}
}
/* Check the link status. */
for (tout = 0; tout < 0x10000; tout++)
{
regv = ReadPHY (PHY_REG_STS);
// value changed from 0x00001 to 0x001C
if (regv & 0x001C)
{
/* Link is on. */
break;
}
}
//Cofigure duplexing and speed
MAC_MAC2 = 0x00000030; /* half duplex, CRC and PAD enabled. */
MAC_SUPP |= 0x0100; /* RMII Support Reg. speed is set to 100M
*/
MAC_COMMAND |= 0x00000240;
/* back to back int-packet gap */
MAC_IPGT = 0x0012; /* IPG setting in half duplex mode */
/* write the station address registers */
MAC_SA0 = EMAC_ADDR12;
MAC_SA1 = EMAC_ADDR34;
MAC_SA2 = EMAC_ADDR56;
EMACTxDescriptorInit();
EMAC_TxEnable();
EMAC_RxEnable();
MAC_MAC1 |=0x0003; //pass all,rx enable
return ( TRUE );
}
DWORD EMACSend( DWORD *EMACBuf, DWORD length )
{
DWORD *tx_desc_addr;
DWORD TxProduceIndex;
DWORD TxConsumeIndex;
DWORD i, templen;
TxProduceIndex = MAC_TXPRODUCEINDEX;
TxConsumeIndex = MAC_TXCONSUMEINDEX;
if ( TxConsumeIndex != TxProduceIndex )
{
return ( FALSE );
}
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
/* reach the limit, that probably should never happen */
/* To be tested */
MAC_TXPRODUCEINDEX = 0;
}
if ( length > EMAC_BLOCK_SIZE )
{
templen = length;
for ( i = 0; (DWORD)(length/EMAC_BLOCK_SIZE) + 1; i++ )
{
templen = length - EMAC_BLOCK_SIZE;
/* two words at a time, packet and control */
tx_desc_addr = (DWORD *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
if ( templen % EMAC_BLOCK_SIZE )
{
/* full block */
*tx_desc_addr = (DWORD)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (DWORD)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE -1));
TxProduceIndex++;
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now */
EMAC_TxEnable();
}
else
{
/* last fragment */
*tx_desc_addr = (DWORD)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (DWORD)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST |
(templen -1) );
TxProduceIndex++; /* transmit now */
EMAC_TxEnable();
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now */
break;
}
}
}
else
{
tx_desc_addr = (DWORD *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
*tx_desc_addr = (DWORD)(EMACBuf);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (DWORD)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST |
(length -1));
TxProduceIndex++; /* transmit now */
EMAC_TxEnable();
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex;
}
return ( TRUE );
}
/
***********************************************************************e
nd of emac.c
***********************************************************************/
/***********************************************************************
crc32.c file
***********************************************************************/
#include "LPC23xx.h" /* LPC23xx/24xx definitions */
#include "type.h"
#include "crc32.h"
void crc32_init(DWORD *pCRC)
{
*pCRC = 0xffffffff;
}
//Calculate CRC value one at a time
void crc32_add(DWORD *pCRC, BYTE val8)
{
DWORD i, poly;
DWORD entry;
DWORD crc_in;
DWORD crc_out;
crc_in = *pCRC;
poly = 0xEDB88320L;
entry = (crc_in ^ ((DWORD) val8)) & 0xFF;
for (i = 0; i < 8; i++)
{
if (entry & 1)
entry = (entry >> 1) ^ poly;
else
entry >>= 1;
}
crc_out = ((crc_in>>8) & 0x00FFFFFF) ^ entry;
*pCRC = crc_out;
return;
}
//finish crc calculation
void crc32_end(DWORD *pCRC)
{
*pCRC ^= 0xffffffff;
}
// CRC buffer
DWORD crc32_bfr(void *pBfr, DWORD size)
{
DWORD crc32;
BYTE *pu8;
crc32_init(&crc32);
pu8 = (BYTE *) pBfr;
while (size-- != 0)
{
crc32_add(&crc32, *pu8);
pu8++ ;
}
crc32_end(&crc32);
return ( crc32 );
}
// calculate CRC
DWORD do_crc_behav( long long Addr )
{
/* state variables */
int crc;
/* declare temporary variables */
int q0, q1, q2, q3;
/* loop variables */
int i, j, d;
/* calculate CRC */
crc = 0xFFFFFFFF;
/* do for each byte */
for (i = 5; i >= 0; i--)
{
d = Addr >> (i * 8);
for (j = 0; j < 2; j++)
{ /* calculate temporary variables */
/* bits: 26,23,22,16,12,11,10,8,7,5,4,2,1,0 */
q3 = (((crc >> 28) ^ (d >> 3)) & 0x00000001) ? 0x04C11DB7 : 0x00000000;
/* bits: 27,24,23,17,13,12,11,9,8,6,5,3,2,1 */
q2 = (((crc >> 29) ^ (d >> 2)) & 0x00000001) ? 0x09823B6E : 0x00000000;
/* bits: 28,25,24,18,14,13,12,10,9,7,6,4,3,2 */
q1 = (((crc >> 30) ^ (d >> 1)) & 0x00000001) ? 0x130476DC : 0x00000000;
/* bits: 29,26,25,19,15,14,13,11,10,8,7,5,4,3 */
q0 = (((crc >> 31) ^ d) & 0x00000001) ? 0x2608EDB8 : 0x00000000;
crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0; /* do crc */
d >>= 4; /* shift data */
} }
return ( crc ); }
/
************************************************************************
*****
* emac.h: Header file for NXP LPC230x Family Microprocessors
***********************************************************************/
#ifndef __EMAC_H
#define __EMAC_H
/* This is the MAC address of MCB23xx/24xx */
#define EMAC_ADDR12 0x00008906
#define EMAC_ADDR34 0x000001F1
#define EMAC_ADDR56 0x00001A00
/* A pseudo destination MAC address is defined for both TX_ONLY and
BOUNCE_RX test */
#define EMAC_DST_ADDR12 0x0000FFFF
#define EMAC_DST_ADDR34 0x0000FFFF
#define EMAC_DST_ADDR56 0x0000FFFF
/* PHY_ADDR, by default, AD0 has pull-up, AD1~4 have pull-downs,
so, the default address is 0x0001, except for Embedded Artists board */
#if EA_BOARD_LPC24XX
#define PHY_ADDR (0x0000 << 8) /* in MAC_MADR, bit 8~12 */
#else
#define PHY_ADDR (0x0001 << 8) /* in MAC_MADR, bit 8~12 */
#endif
/* MAC Configuration Register 1 */
#define MAC1_REC_EN 0x00000001 /* Receive Enable */
#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */
#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */
#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */
#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */
#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */
#define MAC1_RES_MCS_TX 0x00000200 /*Reset MAC TX Control Sublayer */
#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */
#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control */
#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */
#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */
/* MAC Configuration Register 2 */
#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */
#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */
#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */
#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */
#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */
#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */
#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */
#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */
#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */
#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */
#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */
#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre */
#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */
/* Back-to-Back Inter-Packet-Gap Register */
#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */
#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */
/* Non Back-to-Back Inter-Packet-Gap Register */
#define IPGR_DEF 0x00000012 /* Recommended value */
/* Collision Window/Retry Register */
#define CLRT_DEF 0x0000370F /* Default value */
/* PHY Support Register */
#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */
#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */
/* Test Register */
#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */
#define TEST_TST_PAUSE 0x00000002 /* Test Pause */
#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */
/* MII Management Configuration Register */
#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */
#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */
#define MCFG_CLK_SEL 0x0000001C /* Clock Select Mask */
#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */
/* MII Management Command Register */
#define MCMD_READ 0x00000001 /* MII Read */
#define MCMD_SCAN 0x00000002 /* MII Scan continuously */
#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */
#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */
/* MII Management Address Register */
#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */
#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */
/* MII Management Indicators Register */
#define MIND_BUSY 0x00000001 /* MII is Busy */
#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */
#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */
#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */
/* Command Register */
#define CR_RX_EN 0x00000001 /* Enable Receive */
#define CR_TX_EN 0x00000002 /* Enable Transmit */
#define CR_REG_RES 0x00000008 /* Reset Host Registers */
#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */
#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */
#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */
#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */
#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */
#define CR_RMII 0x00000200 /* Reduced MII Interface */
#define CR_FULL_DUP 0x00000400 /* Full Duplex */
/* Status Register */
#define SR_RX_EN 0x00000001 /* Enable Receive */
#define SR_TX_EN 0x00000002 /* Enable Transmit */
/* Transmit Status Vector 0 Register */
#define TSV0_CRC_ERR 0x00000001 /* CRC error */
#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */
#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */
#define TSV0_DONE 0x00000008 /* Tramsmission Completed */
#define TSV0_MCAST 0x00000010 /* Multicast Destination */
#define TSV0_BCAST 0x00000020 /* Broadcast Destination */
#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */
#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */
#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */
#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */
#define TSV0_GIANT 0x00000400 /* Giant Frame */
#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */
#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */
#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */
#define TSV0_PAUSE 0x20000000 /* Pause Frame */
#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */
#define TSV0_VLAN 0x80000000 /* VLAN Frame */
/* Transmit Status Vector 1 Register */
#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */
#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */
/* Receive Status Vector Register */
#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */
#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */
#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */
#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */
#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */
#define RSV_CRC_ERR 0x00100000 /* CRC Error */
#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */
#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */
#define RSV_REC_OK 0x00800000 /* Frame Received OK */
#define RSV_MCAST 0x01000000 /* Multicast Frame */
#define RSV_BCAST 0x02000000 /* Broadcast Frame */
#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */
#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */
#define RSV_PAUSE 0x10000000 /* Pause Frame */
#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */
#define RSV_VLAN 0x40000000 /* VLAN Frame */
/* Flow Control Counter Register */
#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */
#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */
/* Flow Control Status Register */
#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */
/* Receive Filter Control Register */
#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */
#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */
#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */
#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames
*/
#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter
Fram.*/
#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */
#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */
#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */
/* Receive Filter WoL Status/Clear Registers */
#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */
#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */
#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */
#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */
#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */
#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */
#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */
#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */
/* Interrupt Status/Enable/Clear/Set Registers */
#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */
#define INT_RX_ERR 0x00000002 /* Receive Error */
#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */
#define INT_RX_DONE 0x00000008 /* Receive Done */
#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */
#define INT_TX_ERR 0x00000020 /* Transmit Error */
#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */
#define INT_TX_DONE 0x00000080 /* Transmit Done */
#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */
#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */
/* Power Down Register */
#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */
/* RX Descriptor Control Word */
#define RCTRL_SIZE 0x000007FF /* Buffer size mask */
#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */
/* RX Status Hash CRC Word */
#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */
#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */
/* RX Status Information Word */
#define RINFO_SIZE 0x000007FF /* Data size in bytes */
#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */
#define RINFO_VLAN 0x00080000 /* VLAN Frame */
#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */
#define RINFO_MCAST 0x00200000 /* Multicast Frame */
#define RINFO_BCAST 0x00400000 /* Broadcast Frame */
#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */
#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */
#define RINFO_LEN_ERR 0x02000000 /* Length Error */
#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */
#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */
#define RINFO_OVERRUN 0x10000000 /* Receive overrun */
#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */
#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */
#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
#define ETH_MAX_FLEN 1536
/* TX Descriptor Control Word */
#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */
#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */
#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */
#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */
#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */
#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */
#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */
/* TX Status Information Word */
#define TINFO_COL_CNT 0x01E00000 /* Collision Count */
#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */
#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */
#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */
#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */
#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */
#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */
#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */
/* Standard PHY regisers, among all the PHY available, all
the standard PHY register set should be very much the same.
However, all the manufacture have their own extended register
set. */
#define PHY_BMCR 0x0000
#define PHY_BMSR 0x0001
#define PHY_PHYIDR1 0x0002
#define PHY_PHYIDR2 0x0003
#define PHY_ANAR 0x0004
#define PHY_ANLPAR 0x0005
#define PHY_ANLPARNP 0x0005
#define PHY_ANER 0x0006
#define PHY_ANNPTR 0x0007
#define PHY_REG_STS 0x1F
#define PHY_AUTO_NEG 0x1200
/* Extended PHY registers */
/* Below is the National PHY definition used for Keil LPC23xx
and NXP internal engineering board. */
#define NSM_PHY_PHYSTS 0x0010
#define NSM_PHY_MICR 0x0011
#define NSM_PHY_MISR 0x0012
#define NSM_PHY_RESERVED1 0x0013
#define NSM_PHY_FCSCR 0x0014
#define NSM_PHY_RECR 0x0015
#define NSM_PHY_PCSR 0x0016
#define NSM_PHY_RBR
0x0017
#define NSM_PHY_LEDCR 0x0018
#define NSM_PHY_PHYCR 0x0019
#define NSM_PHY_10BTSCR 0x001A
#define NSM_PHY_CDCTRL1 0x001B
#define NSM_PHY_RESERVED2 0x001C
#define NSM_PHY_EDCR 0x001D
/* Below is the Micrel PHY definition used for IAR LPC23xx and
Embedded Artists LPC24xx board. */
#define MIC_PHY_RXER_CNT 0x0015
#define MIC_PHY_INT_CTRL 0x001B
#define MIC_PHY_LINKMD_CTRL 0x001D
#define MIC_PHY_PHY_CTRL 0x001E
#define MIC_PHY_100BASE_PHY_CTRL 0x001F
/* BMCR setting */
#define BMCR_RESET 0x8000
#define BMCR_LOOPBACK 0x4000
#define BMCR_SPEED_100 0x2000
#define BMCR_AN 0x1000
#define BMCR_POWERDOWN 0x0800
#define BMCR_ISOLATE 0x0400
#define BMCR_RE_AN 0x0200
#define BMCR_DUPLEX 0x0100
/* BMSR setting */
#define BMSR_100BE_T4 0x8000
#define BMSR_100TX_FULL 0x4000
#define BMSR_100TX_HALF 0x2000
#define BMSR_10BE_FULL 0x1000
#define BMSR_10BE_HALF 0x0800
#define BMSR_AUTO_DONE 0x0020
#define BMSR_REMOTE_FAULT 0x0010
#define BMSR_NO_AUTO 0x0008
#define BMSR_LINK_ESTABLISHED 0x0004
#define MII_BMSR_TIMEOUT 0x1000000
/* EMAC MODULE ID */
#define PHILIPS_EMAC_MODULE_ID ((0x3902 << 16) | 0x2000)
/* MAC registers and parameters */
#define PCONP_EMAC_CLOCK 0x40000000
#define EMAC_RAM_ADDR 0x7FE00000
#define EMAC_RAM_SIZE 0x00004000
#define EMAC_TX_DESCRIPTOR_COUNT 0x0010
#define EMAC_RX_DESCRIPTOR_COUNT 0x0010
#define TX_DESCRIPTOR_SIZE(EMAC_TX_DESCRIPTOR_COUNT * 8)
#define RX_DESCRIPTOR_SIZE(EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TX_STATUS_SIZE (EMAC_TX_DESCRIPTOR_COUNT * 4)
#define RX_STATUS_SIZE (EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TOTAL_DESCRIPTOR_SIZE (TX_DESCRIPTOR_SIZE +
RX_DESCRIPTOR_SIZE + TX_STATUS_SIZE + RX_STATUS_SIZE)
#define EMAC_DESCRIPTOR_ADDR (EMAC_RAM_ADDR +
EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE)
#define TX_DESCRIPTOR_ADDREMAC_DESCRIPTOR_ADDR
#define TX_STATUS_ADDR (EMAC_DESCRIPTOR_ADDR +
TX_DESCRIPTOR_SIZE)
#define RX_DESCRIPTOR_ADDR(TX_STATUS_ADDR + TX_STATUS_SIZE)
#define RX_STATUS_ADDR (RX_DESCRIPTOR_ADDR +
RX_DESCRIPTOR_SIZE)
#define EMAC_DMA_ADDR EMAC_RAM_ADDR
#define EMAC_DMA_SIZE EMAC_RAM_ADDR + EMAC_RAM_END -
TOTAL_DESCRIPTOR_SIZE
#define EMAC_BLOCK_SIZE 0x2F
#define EMAC_TX_BLOCK_NUM 5
#define EMAC_RX_BLOCK_NUM 5
#define TOTAL_EMAC_BLOCK_NUM 10
#define EMAC_BUFFER_SIZE (EMAC_BLOCK_SIZE *
(EMAC_TX_BLOCK_NUM + EMAC_RX_BLOCK_NUM ))
#define EMAC_TX_BUFFER_ADDREMAC_RAM_ADDR
#define EMAC_RX_BUFFER_ADDR (EMAC_RAM_ADDR +
EMAC_BLOCK_SIZE * EMAC_TX_BLOCK_NUM)
/* EMAC TX DMA Descriptor */
typedef struct _EMAC_TX_DESCRIPTOR {
DWORD TXPacketAddr; /* TX DMA Buffer Address */
DWORD TXControl;
} EMAC_TX_DESCRIPTOR;
typedef struct _EMAC_RX_DESCRIPTOR
{
DWORD RXPacketAddr; /* RX DMA Buffer Address */
DWORD RXControl;
} EMAC_RX_DESCRIPTOR;
/* EMAC Descriptor TX and RX Control fields */
#define EMAC_TX_DESC_INT 0x80000000
#define EMAC_TX_DESC_LAST 0x40000000
#define EMAC_TX_DESC_CRC 0x20000000
#define EMAC_TX_DESC_PAD 0x10000000
#define EMAC_TX_DESC_HUGE 0x08000000
#define EMAC_TX_DESC_OVERRIDE0x04000000
#define EMAC_RX_DESC_INT 0x80000000
/* EMAC Descriptor status related definition */
#define TX_DESC_STATUS_ERR 0x80000000
#define TX_DESC_STATUS_NODESC0x40000000
#define TX_DESC_STATUS_UNDERRUN0x20000000
#define TX_DESC_STATUS_LCOL 0x10000000
#define TX_DESC_STATUS_ECOL 0x08000000
#define TX_DESC_STATUS_EDEFER0x04000000
#define TX_DESC_STATUS_DEFER 0x02000000
#define TX_DESC_STATUS_COLCNT0x01E00000 /* four bits, it's a mask, not exact
count */
#define RX_DESC_STATUS_ERR 0x80000000
#define RX_DESC_STATUS_LAST 0x40000000
#define RX_DESC_STATUS_NODESC0x20000000
#define RX_DESC_STATUS_OVERRUN0x10000000
#define RX_DESC_STATUS_ALGNERR0x08000000
#define RX_DESC_STATUS_RNGERR0x04000000
#define RX_DESC_STATUS_LENERR0x02000000
#define RX_DESC_STATUS_SYMERR0x01000000
#define RX_DESC_STATUS_CRCERR0x00800000
#define RX_DESC_STATUS_BCAST0x00400000
#define RX_DESC_STATUS_MCAST0x00200000
#define RX_DESC_STATUS_FAILFLT0x00100000
#define RX_DESC_STATUS_VLAN 0x00080000
#define RX_DESC_STATUS_CTLFRAM0x00040000
#define DESC_SIZE_MASK 0x000007FF
#define EMAC_INT_RXOVERRUN 0x01 << 0
#define EMAC_INT_RXERROR 0x01 << 1
#define EMAC_INT_RXFINISHED 0x01 << 2
#define EMAC_INT_RXDONE 0x01 << 3
#define EMAC_INT_TXUNDERRUN 0x01 << 4
#define EMAC_INT_TXERROR 0x01 << 5
#define EMAC_INT_TXFINISHED 0x01 << 6
#define EMAC_INT_TXDONE 0x01 << 7
#define EMAC_INT_SOFTINT 0x01 << 12
#define EMAC_INT_WOL 0x01 << 13
#define MAX_PACKET_SIZE 0x600
#define EMAC_HEADER_LENGTH 14
#define DP83848C_ID 0x00221610
#define DP83848C_DEF_ADR 0x0000
extern DWORD PHYInit( DWORD PHYType );
extern void EMACTxDescriptorInit( void );
extern void EMACRxDescriptorInit( void );
extern void EMAC_TxEnable( void );
extern void EMAC_TxDisable( void );
extern void EMAC_RxEnable( void );
extern void EMAC_RxDisable( void );
extern DWORD EMACInit( void );
extern DWORD EMACSend( DWORD *EMACBuf, DWORD length );
extern DWORD EMACReceive( DWORD *EMACBuf );
#endif /* end __EMAC_H */
/
************************************************************************
*****
* End Of File
************************************************************************
******/