⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xllp_ethernet.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 5 页
字号:
                   (macAddressP[0] & 0x00FF), (macAddressP[0] >> 8),
                   (macAddressP[1] & 0x00FF), (macAddressP[1] >> 8),
                   (macAddressP[2] & 0x00FF), (macAddressP[2] >> 8));

    return (loggedError);
}

/******************************************************************************

  Function Name: 
    XllpEthernetStoreEEPROMMACAddress

  Description: 
    This routine saves the specified MAC address into EEPROM.

  Global Register Modified: 
    None 

  Input Arguments:
    P_XLLP_UINT16_T macAddressP - pointer to an array of tree 16-bit words

  Output Arguments:
    None
          
  Return Value: 
    XLLP_UINT32_T - error code in case of failure reading the EEPROM, zero if success.

*******************************************************************************/

XLLP_UINT32_T XllpEthernetStoreEEPROMMACAddress(P_XLLP_UINT16_T macAddressP)
{
    // Assume success.
    loggedError = 0;

    DM_CwDbgPrintf(DM_CW_LAN91C111_0, " Storing MAC address in EEPROM");

    // WARNING: This routine changes the selected Bank register.
    XllpEthernetWriteEEPROM(EEPROM_MAC_OFFSET_1_W, macAddressP[0]);
    if (loggedError)
    {
        DM_CwDbgPrintf(DM_CW_LAN91C111_1, " Timeout writing EEPROM");
        // Error writing the MAC address.
        LOGERROR(&loggedError, 
                 ERR_L_LAN91C111, ERR_S_BAD_MAC, ERR_T_UNEXPECTED, 
                 macAddressP[0], 0, 0);
        return (loggedError);
    }

    // WARNING: This routine changes the selected Bank register.
    XllpEthernetWriteEEPROM(EEPROM_MAC_OFFSET_2_W, macAddressP[1]);
    if (loggedError)
    {
        DM_CwDbgPrintf(DM_CW_LAN91C111_1, " Timeout writing EEPROM");
        // Error writing the MAC address.
        LOGERROR(&loggedError, 
                 ERR_L_LAN91C111, ERR_S_BAD_MAC, ERR_T_UNEXPECTED, 
                 macAddressP[1], 0, 0);
        return (loggedError);
    }

    // WARNING: This routine changes the selected Bank register.
    XllpEthernetWriteEEPROM(EEPROM_MAC_OFFSET_3_W, macAddressP[2]);
    if (loggedError)
    {
        DM_CwDbgPrintf(DM_CW_LAN91C111_1, " Timeout writing EEPROM");
        // Error writing the MAC address.
        LOGERROR(&loggedError, 
                 ERR_L_LAN91C111, ERR_S_BAD_MAC, ERR_T_UNEXPECTED, 
                 macAddressP[2], 0, 0);
        return (loggedError);
    }

    DM_CwDbgPrintf(DM_CW_LAN91C111_0,
                   " EEPROM LAN91C111 MAC Address: %02X-%02X-%02X-%02X-%02X-%02X",
                   (macAddressP[0] & 0x00FF), (macAddressP[0] >> 8),
                   (macAddressP[1] & 0x00FF), (macAddressP[1] >> 8),
                   (macAddressP[2] & 0x00FF), (macAddressP[2] >> 8));

    return (loggedError);
}

/******************************************************************************

  Function Name: 
    XllpEthernetGetMACAddress

  Description: 
    This routine return the current MAC address, read from the IA0-IA5 registers.

  Global Register Modified: 
    None 

  Input Arguments:
    P_XLLP_UINT16_T macAddressP - pointer to an array of tree 16-bit words

  Output Arguments:
    None
          
  Return Value: 
    XLLP_UINT32_T - error code in case of failure reading the EEPROM, zero if success.

*******************************************************************************/

void XllpEthernetGetMACAddress(P_XLLP_UINT16_T macAddressP)
{
    DM_CwDbgPrintf(DM_CW_LAN91C111_0, " Reading MAC address");

    // Read the MAC address from the LAN91C111. This gets read from the EEPROM
    // by the LAN91C111 during reset. This assumes Bank 1 is selected.
    XllpEthernetSelectRegisterBank (BANK1);
    macAddressP[0] = XllpEthernetReadWord(XLLP_LAN91C111_IA0);
    macAddressP[1] = XllpEthernetReadWord(XLLP_LAN91C111_IA2);
    macAddressP[2] = XllpEthernetReadWord(XLLP_LAN91C111_IA4);

    DM_CwDbgPrintf(DM_CW_LAN91C111_0,
                   " LAN91C111 MAC Address: %02X-%02X-%02X-%02X-%02X-%02X",
                   (macAddressP[0] & 0x00FF), (macAddressP[0] >> 8),
                   (macAddressP[1] & 0x00FF), (macAddressP[1] >> 8),
                   (macAddressP[2] & 0x00FF), (macAddressP[2] >> 8));
}

/******************************************************************************

  Function Name: 
    XllpEthernetStoreMACAddress

  Description: 
    This routine saves the MAC address in the IA0-IA5 registers.

  Global Register Modified: 
    None 

  Input Arguments:
    P_XLLP_UINT16_T macAddressP - pointer to an array of tree 16-bit words

  Output Arguments:
    None
          
  Return Value: 
    None

*******************************************************************************/

void XllpEthernetStoreMACAddress(P_XLLP_UINT16_T macAddressP)
{
    DM_CwDbgPrintf(DM_CW_LAN91C111_0, " Storing MAC address");

    // Access the I/O space and select Bank 1.
    XllpEthernetSelectRegisterBank (BANK1);

    // Write the generated MAC address to the LAN91C111.
    XllpEthernetWriteWord(macAddressP[0], XLLP_LAN91C111_IA0);
    XllpEthernetWriteWord(macAddressP[1], XLLP_LAN91C111_IA2);
    XllpEthernetWriteWord(macAddressP[2], XLLP_LAN91C111_IA4);

    DM_CwDbgPrintf(DM_CW_LAN91C111_0,
                   " LAN91C111 MAC Address: %02X-%02X-%02X-%02X-%02X-%02X",
                   (macAddressP[0] & 0x00FF), (macAddressP[0] >> 8),
                   (macAddressP[1] & 0x00FF), (macAddressP[1] >> 8),
                   (macAddressP[2] & 0x00FF), (macAddressP[2] >> 8));
}

/******************************************************************************

  Function Name: 
    XllpEthernetDeallocateTxPacket

  Description: 
    This function deallocates memory after the transmit frame was completed
    by the Ethernet Controller. This function should be used only if the auto
    release feature is not used.

  Global Register Modified: 
    None. 

  Input Arguments:
    None

  Output Arguments:
    None
          
  Return Value: 
    XLLP_UINT32_T - TRUE if success, FALSE if failed

*******************************************************************************/

static
XLLP_UINT32_T XllpEthernetDeallocateTxPacket(void)
{
    XLLP_UINT32_T start, timebase = getTimebase();
    XLLP_UINT32_T timeout = XLLP_LAN91C111_TO_ALLOC * timebase;
    XLLP_UINT16_T resultCode;
    XLLP_UINT8_T intStatus;

	loggedError = 0;

    // Get the transmit status.
    XllpEthernetSelectRegisterBank (BANK2);
    XllpEthernetWriteWord(XLLP_LAN91C111_PTR_READ, XLLP_LAN91C111_POINTER);
    resultCode = XllpEthernetReadWord16(XLLP_LAN91C111_DATA_HIGH);

    // Clear the statistics register.
    XllpEthernetSelectRegisterBank (BANK1);
    XllpEthernetReadWord(XLLP_LAN91C111_COUNTER);
    // Re-enable TXENA in the Transmit Control Register.
    XllpEthernetWriteWord((XLLP_UINT16_T)XLLP_LAN91C111_TCR_TXENA | XllpEthernetReadWord(XLLP_LAN91C111_TCR), XLLP_LAN91C111_TCR);

    // Release the memory in the buffer for the frame that failed.
    XllpEthernetSelectRegisterBank (BANK2);
    XllpEthernetWriteWord16(XLLP_LAN91C111_MMUCR_RELEASE_TX, XLLP_LAN91C111_MMU);

    // Prepare for timeout by getting the initial time interval.
    start = TimerRegBaseP->oscr0;

    // Wait for the request to complete by monitoring the NO BUSY bit in
    // the MMU Command Register.
    while (!XllpEthernetReadWord(XLLP_LAN91C111_MMU) & XLLP_LAN91C111_MMUCR_NO_BUSY)
    {
        // Get the current time interval.
        if (getDelta(TimerRegBaseP, start) > timeout)
        {
            DM_CwDbgPrintf(DM_CW_LAN91C111_1, " Error deallocating Tx frame");
            // Report timeout error.
            LOGERROR(&loggedError, 
                     ERR_L_LAN91C111, ERR_S_DEALLOC, ERR_T_TIMEOUT, 
                     0, 0, 0);
            return (loggedError);
        }
    }

    // Get the Interrupt Status Register.
    intStatus = XllpEthernetReadByte(XLLP_LAN91C111_INT_STATS);
    // Enable transmit interrupt if set.
    if (intStatus & XLLP_LAN91C111_IST_TX_INT)
    {
        // Acknowledge the Transmit interrupt.
        XllpEthernetWriteByte(intStatus | (XLLP_UINT8_T)XLLP_LAN91C111_IST_TX_INT, XLLP_LAN91C111_INT_ACK);
    }

    return (0);
}

/******************************************************************************

  Function Name: 
    XllpEthernetAllocateTxPacket

  Description: 
    This function allocates memory for the transmit from the Ethernet Controller

  Global Register Modified: 
    None. 

  Input Arguments:
    None

  Output Arguments:
    P_XLLP_UINT16_T packetHandle - return a packet number that was allocated
          
  Return Value: 
    XLLP_UINT32_T - TRUE if success, FALSE if failed

*******************************************************************************/

static
XLLP_UINT32_T XllpEthernetAllocateTxPacket (P_XLLP_UINT16_T packetHandle)
{
    XLLP_UINT32_T errorCode = 0;
    XLLP_UINT16_T tempValue;
    XLLP_UINT16_T lastPacket;
    XLLP_UINT8_T status;
    XLLP_UINT32_T start, timebase = getTimebase();
    XLLP_UINT32_T timeout = XLLP_LAN91C111_TO_TRANSMIT * timebase;
    XLLP_UINT16_T lanReg;

	loggedError = 0;

    // Read the Control Register.
    lanReg = XllpEthernetReadWord(XLLP_LAN91C111_CONTROL);
    // Check the auto release bit to determine if we should release the buffer.
    if (!(lanReg & XLLP_LAN91C111_CTR_AUTO_RELEASE))
    {
    	XllpEthernetDeallocateTxPacket();
    }

    // Allocate memory in the buffer for the frame.
    XllpEthernetSelectRegisterBank (BANK2);
    XllpEthernetWriteWord16(XLLP_LAN91C111_MMUCR_ALLOC_TX, XLLP_LAN91C111_MMU);


    start = TimerRegBaseP->oscr0;
    // Wait for the request to complete by monitoring the ALLOC INT bit in
    // the Interrupt Status Register.
    while (!((status = XllpEthernetReadByte(XLLP_LAN91C111_INT_STATS)) & XLLP_LAN91C111_IST_ALLOC_INT))
    {
        if (getDelta(TimerRegBaseP, start) > timeout)
        {
            DM_CwDbgPrintf(DM_CW_LAN91C111_1, " Error allocating Tx frame");
            LOGERROR(&loggedError, 
                     ERR_L_LAN91C111, ERR_S_ALLOC, ERR_T_NOTRANSMIT, 
                     0, 0, 0);
            errorCode = loggedError;
			break;
		}
	}

    if (status & XLLP_LAN91C111_IST_ALLOC_INT)
    {
        // Get the packet number just allocated.
        tempValue = XllpEthernetReadWord(XLLP_LAN91C111_PNR);
        lastPacket = (tempValue >> 8) & 0x7;
        *packetHandle = lastPacket; 
    }

    return (errorCode);
}

/******************************************************************************

  Function Name: 
    XllpEthernetSetLoopBack

  Description: 
    This function puts the Ethernet Controller into one of the three loopback modes:
    EPH loopback - where the packet is looped back immediately after the EPH block,
                   The packet never reaches the MII bus or the internal PHY.
    PHY half loopback - where the packet is sent out of the MAC, through the internal PHY
                   and loops back after crossing MII bus. PHY half duplex mode should
                   be used to allow MAC to receive a packet with its own source address.
    PHY full loopback - is used for external loopback. The packet is sent out of the MAC, 
                   through the internal PHY, out of RJ45 connector and loops back through
                   external wiring.                    

  Global Register Modified: 
    None 

  Input Arguments:
    LAN91C111LoopbackTypeT   type     - a type of the loopback 
    LAN91C111LoopbackEnableT enable   - the loopback is enabled if one, disabled if zero

  Output Arguments:
    None
          
  Return Value: 
    None

*******************************************************************************/

void XllpEthernetSetLoopBack(XllpEthernetLoopbackTypeT type,
						     XllpEthernetLoopbackEnableT enable)
{
    XLLP_UINT16_T TCR;
    XLLP_UINT16_T RPCR;

    // Select Bank 0
    XllpEthernetSelectRegisterBank (BANK0);
    // Get the Transmit Control Register.
    TCR = XllpEthernetReadWord(XLLP_LAN91C111_TCR);
    // Get the RPCR Register.
    RPCR = XllpEthernetReadWord(XLLP_LAN91C111_RPCR);

    if (type == XLLP_ETHERNET_EPH_LOOPBACK)
    {
        // EPH Loopback test
        if (enable)
        {
            TCR |= XLLP_LAN91C111_TCR_EPH_LOOP;
        }
        else
        {
            // Clear internal loopback.
            TCR &= ~XLLP_LAN91C111_TCR_EPH_LOOP;
        }
    }
    else if (type == XLLP_ETHERNET_PHY_FULL_LOOPBACK)
    {
        // PHY Loopback test with full duplex
        if (enable)
        {
            TCR |= XLLP_LAN91C111_TCR_SWFDUP;
            RPCR |= XLLP_LAN91C111_RPCR_DPLX;
        }
        else
        {
            // Clear internal loopback.
            TCR &= (~XLLP_LAN91C111_TCR_SWFDUP & ~XLLP_LAN91C111_TCR_FDUPLX);
            RPCR &= ~XLLP_LAN91C111_RPCR_DPLX;
        }
    }
    else if (type == XLLP_ETHERNET_PHY_HALF_LOOPBACK)
    {
        // PHY Loopback test with half duplex
        if (enable)
        {
            TCR |= XLLP_LAN91C111_TCR_FDUPLX;
        }
        else
        {
            // Clear internal loopback.
            TCR &= ~XLLP_LAN91C111_TCR_FDUPLX;
        }

	}
    // Update the Transmit Control Register.
    XllpEthernetWriteWord(TCR, XLLP_LAN91C111_TCR);
    // Update the RPCR Register.
    XllpEthernetWriteWord(RPCR, XLLP_LAN91C111_RPCR);
}

/******************************************************************************

  Function Name: 
    XllpEthernetDumpFrame

  Description: 
    This routine used for debugging to display the ethernet frame.

  Global Register Modified: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -