📄 ne64driver.c
字号:
{
_DEBUGT("ptrc=0 (read ptime) ");
ptime=PTIME; /* return current PAUSE counter value */
}
_DEBUGT(" ptime = "); _DEBUGI(ptime); _DEBUGT("EtherPause(end)\n\r");
return ptime;
}
//===============================================
void EtherOtherTx(tU08 txpar)
{
_DEBUGT("EtherOtherTx");
TXCTS_PTRC = (txpar & TXCT_PTRC) ? 1:0;
#ifdef ETH_DEBUG
if (TXCTS_PTRC) _DEBUGT(" PTRC");
#endif
if (!TXCTS_TXACT)
{
TXCTS_SSB= (txpar & TXCT_SSB) ? 1 : 0;
#ifdef ETH_DEBUG
if (TXCTS_SSB) _DEBUGT(" SSB");
#endif
}
else
{
_DEBUGT(" TX in progress - SSB not changed");
}
}
//===============================================
void EtherStartFrameTransmission(tU16 datalen)
{
datalen = datalen +14;
_DEBUGT("-TXSTART-");
/* check & fix the length if incorrect */
#if EMAC_TX_SZ > 1514
/* truncate if longer than Ethernet limit */
if (datalen > 1514) datalen=1514;
#else
/* truncate if longer than TX FIFO buffer limit */
if (datalen > EMAC_TX_SZ) datalen=EMAC_TX_SZ;
#endif
/* extend if shorter -> however this might be security flaw
as we do not know what data are stored beyond our frame */
if (datalen < 60) datalen=60;
/* set the offset where the last frame byte resides in FIFO */
TXEFP=datalen-1;
//Wait for TX idle
while (TXCTS_TXACT == 1);
/* issue a transmit command */
TXCTS_TCMD=TCMD_START;
_DEBUGT( "-TXEND-");
}
//=======================================================================
//SW LED control
#if USE_EXTBUS
void ExternalBusCfg() {
//Change bus clock to external bus 16 Mhz maximum
CLKSEL=0;
CLKSEL_PLLSEL = 0; /* Select clock source from XTAL */
PLLCTL_PLLON = 0; /* Disable the PLL */
SYNR = 8; /* Set the multiplier register */
REFDV = 13; /* Set the divider register */
PLLCTL = 192;
PLLCTL_PLLON = 1; /* Enable the PLL */
while(!CRGFLG_LOCK); /* Wait */
CLKSEL_PLLSEL = 1; /* Select clock source from PLL */
//Configure to External Bus Mode
//The following must not use BSET instructions.
RDRIV = 0x00;
PEAR = 0x0C; // ((LSTRE|RDWE)&~NECLK)
EBICTL = 0x01; // Enable clock stretching (ESTR)
MISC = 0x05; // (~EXSTR1+EXSTR0+~ROMHM+ROMON)
MODE = 0xE2; // (MODC+MODB+MODA+EMK+~EME)
}
#endif
//=======================================================================
//SW LED control
#if USE_SWLED
void UseSWLedRun() {
LEDcounter = LEDcounter +1;
if (LEDcounter == 9500) {
LEDcounter = 0;
PTL_PTL0 = 1; //Turn off ACTLED
PTL_PTL4 = 1; //Turn off COLLED
}
}
#endif
//==========================================================================
// NE64 Interrupts
//==========================================================================
#pragma CODE_SEG NON_BANKED
//=======================================================================
///EPHY ISR - Type of EPHY interrupt detemined by MII read of PHY_REG_IR register
//=======================================================================
interrupt void ephy_isr(void)
{
tU16 mymrdata, isr_read, temp, temp2;
tU16 none_of_these;
none_of_these = 0;
_DEBUGT("\r\n***EPHY_ISR\r\n ");
//@@@@@@@@@@@@@@@@
//STEP1: PHY interrupt flag clearing. Read PHY_REG_IR to determine PHY intterrupt
// Need to read MII Inter. register 22 before clearing EPHYIF
//@@@@@@@@@@@@@@@@
while ( !(MIIread(PHY_ADDRESS, PHY_REG_IR, &isr_read)) );
//@@@@@@@@@@@@@@@@
//STEP2: Process PHY interrupt register 0x10 (PHY_REG_IR) contenets
//handlers for different interrupts flags
//@@@@@@@@@@@@@@@@
_DEBUGT(" \r\nPHY Interrupt:\r\n"); _DEBUGT(" =================\r\n");
#if AUTO_NEG
//***********************
//Acknowledge Bit Received
//***********************
if ((isr_read & PHY_R16_ACKR) == PHY_R16_ACKR) {
_DEBUGT(" ###PHY_R16_ACKR=ACK BIT RX###\r\n ");
none_of_these = none_of_these + 1;
//code here
}
//***********************
//Link Partner Page Received
//***********************
if ((isr_read & PHY_R16_PGR) == PHY_R16_PGR) {
_DEBUGT(" ###PHY_R16_PGR=LINK PARTERN PAGE###\r\n ");
none_of_these = none_of_these + 1;
//code here
//Just checking what link partners ablility is!!!!!!! and Expansion Register
while ( ! (MIIread(PHY_ADDRESS, PHY_REG_ANLPAR, &mymrdata)) );
while ( ! (MIIread(PHY_ADDRESS, PHY_REG_ER, &mymrdata)) );
_DEBUGNL;
}
//***********************
//Auto-Negotiation Changed Enable
//***********************
if ((isr_read & PHY_R16_ANC) == PHY_R16_ANC) {
_DEBUGT(" ###PHY_R16_ANC=AUTONEG CHANGE###\r\n ");
none_of_these = none_of_these + 1;
//Read Proprietary Status Register (PSR) for status
while ( !(MIIread(PHY_ADDRESS, PHY_REG_PSR, &mymrdata)) );
//CHECK PSR:Is auto_neg complete?
if ((mymrdata & PHY_R17_ANNC) == PHY_R17_ANNC) {
//AUTONEG COMPLETED
_DEBUGT("\r\n -AUTONEG COMPLETED ");
//CHECK PSR: Was a commom mode found?
if ((mymrdata & PHY_R17_ANCM) == PHY_R17_ANCM ) _DEBUGT(" - &&&NO COMMON_MODE&&&\r\n");
else _DEBUGT(" &&&COMMON_MODE&&&\r\n");
//CHECK PSR: Duplex (verify/set EMAC duplex resolution
//Use temp as temp to save duplex setting
temp = 33;
if ((mymrdata & PHY_R17_DPM) == PHY_R17_DPM ) {
//Set EMAC to FULL Duplex
_DEBUGT(" ###AUTONEG:SET EMAC Full Duplex###\r\n");
EmacDisable();
EmacControl(NETCTL | NETCT_FDX);
EmacEnable();
//Use temp as temp to save duplex setting
temp = 55;
}
else {
//Set EMAC to HALF Duplex
_DEBUGT(" ###AUTONEG:SET EMAC Half Duplex###\r\n");
EmacDisable();
EmacControl(NETCTL & ~NETCT_FDX);
EmacEnable();
//Use temp as temp to save duplex setting
temp = 11;
}
//Read PHY_REG_ANLPAR register to check if xflow abitily
while ( !(MIIread(PHY_ADDRESS, PHY_REG_ANLPAR, &mymrdata) ) );
#if XFLOWC
if ( ((mymrdata & PHY_R5_FCTL) == PHY_R5_FCTL) && (temp == 55)) {
gotxflowc = 1; _DEBUGT("<<PAUSE RESOLVED>>\r\n");
}
else {
gotxflowc = 0; _DEBUGT("<<NO PAUSE>>\r\n");
}
#endif //#if XFLOWC
_DEBUGNL;
} //if ((mymrdata & PHY_R17_ANNC) == PHY_R17_ANNC)
else {
//AUTONEG NOT COMPLETED
_DEBUGT("\r\n AUTONEG NOT COMPLETED ");
}
}
#endif //#if AUTO_NEG
//***********************
//Link Changed
//***********************
if ((isr_read & PHY_R16_LKC) == PHY_R16_LKC) {
_DEBUGT(" ###PHY_R16_LKC=LINK CHANGE###");
none_of_these = none_of_these + 1;
//Read Proprietary Status Register (PSR) for status
while ( !(MIIread(PHY_ADDRESS, PHY_REG_PSR, &mymrdata)) );
//CHECK PSR:Is link down???
if ((mymrdata & PHY_R17_LNK) == PHY_R17_LNK) {
//No link present
gotlink = 0;
_DEBUGT("@@@@LINK IS DOWN@@@@\r\n ");
//Restart Autoneg is link is down
#if AUTO_NEG
//Read EPHY control register
while ( !(MIIread(PHY_ADDRESS, PHY_REG_CR, &mymrdata)) );
_DEBUGT("@@@READ PHY_REG_CR WHEN LINK DOWN@@@\r\n");
//Write EPHY control register to set and restart auto negotiation
_DEBUGT(" \r\n@@@@SET AND RESTART AUTONEG@@@@\r\n ");
while ( !(MIIwrite(PHY_ADDRESS, PHY_REG_CR, mymrdata | PHY_R0_ANE | PHY_R0_RAN )) );
#endif //#if AUTO_NEG
#if USE_SWLED
PTL_PTL0 = 1; //turn LED off
PTL_PTL1 = 1; //turn LED off
PTL_PTL2 = 1; //turn LED off
PTL_PTL3 = 1; //turn LED off
PTL_PTL4 = 1; //turn LED off
#endif
}
else
{
//No link present
gotlink = 1;
_DEBUGNL;_DEBUGT("@@@@LINK IS UP@@@@\r\n ");_DEBUGNL;
#if USE_SWLED
#if LNKLED
PTL_PTL1 = 0; //turn LNKLED on
#endif
//Read Proprietary Status Register (PSR) for status
while ( !(MIIread(PHY_ADDRESS, PHY_REG_PSR, &mymrdata)) );
//CHECK PSR:DUP?
#if DUPLED
if ((mymrdata & PHY_R17_DPM) == PHY_R17_DPM ) {
PTL_PTL3 = 0; //turn DUPLED on (Full Duplex)
} else {
PTL_PTL3 = 1; //turn DUPLED off (Half Duplex)
}
#endif
//CHECK PSR:SPD?
#if SPDLED
if ((mymrdata & PHY_R17_SPD) == PHY_R17_SPD ) {
PTL_PTL2 = 0; //turn SPDLED on (100 Mbps)
} else {
PTL_PTL2 = 1; //turn SPDLED off (10 Mbps)
}
#endif
#endif
}
}
//***********************
//Parallel Detect Fault Enable
//***********************
if ((isr_read & PHY_R16_PDF) == PHY_R16_PDF) {
_DEBUGT(" ###PHY_R16_PDF = PARALLEL DETECTION FAULT###\r\n ");
none_of_these = none_of_these + 1;
#if AUTO_NEG_TIMEOUT
//Read PHY Control Register 0
while ( !(MIIread(PHY_ADDRESS, PHY_REG_CR, &mymrdata)) );
//Set temp2 to adjust EPHY Duplex to HALF duplex for as required by PARALLEL DETECTION
_DEBUGT("***ADJUST EPHY and EMAC TO HALF-DUPLEX***\r\n");
temp2 = mymrdata & ~PHY_R0_DPLX;
//Set EMAC to HALF Duplex
EmacDisable();
EmacControl(NETCTL & ~NETCT_FDX);
EmacEnable();
//Set temp2 to adjust EPHY Speed MANUALLY
#if SPEED100_P
temp2 = temp2 | PHY_R0_DR; //Set SPEED100
#else //ELSE SPEED100
temp2 = temp2 & ~PHY_R0_DR; //Set SPEED10
#endif //SPEED100
//Set temp2 to Disable EPHY Auto negotiation
temp2 = temp2 & ~PHY_R0_ANE;
//Write temp2 settings to EPHY Config Register
_DEBUGT(" ***DISABLE AUTONEG AND FIX SPEED?DUPLEX***\r\n");
while ( !(MIIwrite(PHY_ADDRESS, PHY_REG_CR, temp2)) );
#endif //AUTO_NEG_TIMEOUT
}
//***********************
//Remote Fault Interrupt Enable
//***********************
if ((isr_read & PHY_R16_RMTF) == PHY_R16_RMTF) {
_DEBUGT(" ###PHY_R16_RMTF=REMOTE FAULT###\r\n ");
none_of_these = none_of_these + 1;
//code here
}
//***********************
//Jabber Interrupt Enable
//***********************
if ((isr_read & PHY_R16_JABI) == PHY_R16_JABI) {
_DEBUGT(" ###PHY_R16_JABI=JABBER###\r\n ");
none_of_these = none_of_these + 1;
//code here
}
//***********************
if (none_of_these == 0) _DEBUGT(" - UNKNOWN PHY INT\r\n ");
//***********************
//@@@@@@@@@@@@@@@@
//STEP 3: Clear Flag
//@@@@@@@@@@@@@@@@
EPHYSR = EPHYSR_EPHYIF_MASK; /* Clear the Ephy interrupt flag */
_DEBUGT("\r\n =================\r\n"); _DEBUGT("***EPHYisr_END");
}
//=======================================================================
///RX flow control ISR
//=======================================================================
interrupt void emac_rx_fc_isr(void)
{
_DEBUGT("\r\n***EMAC_RX_XFLOW_ISR");
IEVENT = IEVENT_RFCIF_MASK; /* Clear the flag in Emac */
_DEBUGT("***isr_END");
}
//=======================================================================
///Babbling Receive Error ISR
//=======================================================================
interrupt void emac_b_rx_error_isr(void)
{
_DEBUGT("\r\n***EMAC_RX_BABBLE_ISR");
IEVENT = IEVENT_BREIF_MASK; /* Clear the flag in Emac */
_DEBUGT("***isr_END");
#if (DELETE_BFRAMES && ZERO_COPY)
if (IEVENT & IEVENT_RXACIF_MASK)
{
IEVENT |= IEVENT_RXACIF_MASK;
}
if (IEVENT & IEVENT_RXBCIF_MASK)
{
IEVENT |= IEVENT_RXBCIF_MASK;
}
#endif
}
//=======================================================================
///Receive Error ISR
//=======================================================================
interrupt void emac_rx_error_isr(void)
{
_DEBUGT("\r\n***EMAC_RX_ERROR_ISR");
IEVENT = IEVENT_RXEIF_MASK; /* Clear the flag in Emac */
_DEBUGT("***isr_END");
}
//=======================================================================
///RXAOIF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -