📄 ethernet.c
字号:
//*****************************************************************************
//
// ethernet.c - Driver for the Integrated Ethernet Controller
//
// Copyright (c) 2006-2007 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 1392 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup ethernet_api
//! @{
//
//*****************************************************************************
#include "../hw_ints.h"
#include "../hw_memmap.h"
#include "../hw_types.h"
#include "../hw_ethernet.h"
#include "debug.h"
#include "interrupt.h"
#include "sysctl.h"
#include "ethernet.h"
//*****************************************************************************
//
// Internal function declarations and macros for Ethernet driver.
//
//*****************************************************************************
static long EthernetInternalGetPacket(unsigned long ulBase,
unsigned char *pucBuf,
long lBufLen);
static long EthernetInternalPutPacket(unsigned long ulBase,
unsigned char *pucBuf,
long lBufLen);
//*****************************************************************************
//
//! Initializes the Ethernet Controller for operation.
//!
//! \param ulBase is the base address of the controller.
//!
//! This function will prepare the Ethernet Controller for first time use in
//! a given hardware/software configuration. This function should be called
//! before any other Ethernet API functions are called.
//!
//! \note If the device configuration is changed (e.g. the System Clock is
//! reprogrammed to a different speed), then the Ethernet Controller must be
//! disabled by calling the \e EthernetDisable function and the controller must
//! be reinitialized by calling the EthernetInit function again. After the
//! controller has been reinitialized, the controller should be reconfigured
//! using the appropriate Ethernet API calls.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetInit(unsigned long ulBase)
{
unsigned long ulDiv;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Set the Management Clock Divider register for access to the PHY
// register set (via EthernetPHYRead/Write).
//
// The MDC clock divided down from the system clock using the following
// formula. A maximum of 2.5MHz is allowed for F(mdc).
//
// F(mdc) = F(sys) / (2 * (div + 1))
// div = (F(sys) / (2 * F(mdc))) - 1
// div = (F(sys) / 2 / F(mdc)) - 1
//
// Note: Because we should round up, to ensure we don't violate the
// maximum clock speed, we can simplify this as follows:
//
// div = F(sys) / 2 / F(mdc)
//
// For example, given a system clock of 6.0MHz, and a div value of 1,
// the mdc clock would be programmed as 1.5 MHz.
//
ulDiv = (SysCtlClockGet() / 2) / 2500000;
HWREG(ulBase + MAC_O_MDV) = (ulDiv & MAC_MDV_DIV);
}
//*****************************************************************************
//
//! Sets the configuration of the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//! \param ulConfig is the bit-mapped configuration for the controller.
//!
//! After the \e EthernetInit function has been called, this API function
//! can be used to configure the various features of the Ethernet Controller.
//!
//! The Ethernet Controller provides two control registers that are used
//! to configure the controller's operation. The transmit control register
//! provides settings to enable full duplex operation, to auto-generate the
//! frame check sequence, and to pad the transmit packets to the minimum
//! length as required by the IEEE standard. The receive control register
//! provides settings to enable reception of packets with bad frame check
//! sequence values and to enable multi-cast or promiscuous modes.
//!
//! The parameter \e ulConfig is the logic OR of the following values.
//!
//! - ETH_CFG_RX_BADCRCDIS - Disable reception of packets with a bad CRC
//! - ETH_CFG_RX_PRMSEN - Enable promiscuous mode reception (all packets)
//! - ETH_CFG_RX_AMULEN - Enable reception of multicast packets
//! - ETH_CFG_TX_DPLXEN - Enable full duplex transmit mode
//! - ETH_CFG_TX_CRCEN - Enable transmit with auto CRC generation
//! - ETH_CFG_TX_PADEN - Enable padding of transmit data to minimum size
//!
//! These bit-mapped values are programmed into the transmit and/or receive
//! control register.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetConfigSet(unsigned long ulBase, unsigned long ulConfig)
{
unsigned long ulTemp;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT((ulConfig & ~(ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN |
ETH_CFG_TX_PADEN | ETH_CFG_RX_BADCRCDIS |
ETH_CFG_RX_PRMSEN | ETH_CFG_RX_AMULEN)) == 0);
//
// Setup the Transmit Control Register.
//
ulTemp = HWREG(ulBase + MAC_O_TCTL);
ulTemp &= ~(MAC_TCTL_DUPLEX | MAC_TCTL_CRC | MAC_TCTL_PADEN);
ulTemp |= (ulConfig & 0x0FF);
HWREG(ulBase + MAC_O_TCTL) = ulTemp;
//
// Setup the Receive Control Register.
//
ulTemp = HWREG(ulBase + MAC_O_RCTL);
ulTemp &= ~(MAC_RCTL_BADCRC | MAC_RCTL_PRMS | MAC_RCTL_AMUL);
ulTemp |= ((ulConfig >> 8) & 0x0FF);
HWREG(ulBase + MAC_O_RCTL) = ulTemp;
}
//*****************************************************************************
//
//! Gets the current configuration of the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//!
//! This function will query the control registers of the Ethernet Controller
//! and return a bit-mapped configuration value.
//!
//! \sa The description of the EthernetConfigSet() function provides detailed
//! information for the bit-mapped configuration values that will be returned.
//!
//! \return The bit-mapped Ethernet Controller configuration value.
//
//*****************************************************************************
unsigned long
EthernetConfigGet(unsigned long ulBase)
{
unsigned long ulConfig;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Read and return the Ethernet Controller configuration parameters,
// properly shifted into the appropriate bit field positions.
//
ulConfig = (HWREG(ulBase + MAC_O_RCTL) & ~MAC_RCTL_RXEN) << 8;
ulConfig |= (HWREG(ulBase + MAC_O_TCTL) & ~MAC_TCTL_TXEN);
return(ulConfig);
}
//*****************************************************************************
//
//! Sets the MAC address of the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucMACAddr is the pointer to the array of MAC-48 address octets.
//!
//! This function will program the IEEE defined MAC-48 address specified in
//! \e pucMACAddr into the Ethernet Controller. This address is used by the
//! Ethernet Controller for hardware level filtering of incoming Ethernet
//! packets (when promiscuous mode is not enabled).
//!
//! The MAC-48 address is defined as 6 octets, illustrated by the fictitious
//! address below. The numbers are presented in hexadecimal format.
//!
//! AC-DE-48-00-00-80
//!
//! In this representation, the first three octets (AC-DE-48) are the
//! Organizationally Unique Identifier (OUI). This is a number assigned by
//! the IEEE to an organization that requests a block of MAC addresses. The
//! last three octets are a 24-bit number managed by the OUI owner to uniquely
//! identify a piece of hardware within that organization that is to be
//! connected to the Ethernet.
//!
//! In this representation, the octets are transmitted from left to right,
//! with the "AC" octet being transmitted first and the "80" octet being
//! transmitted last. Within an octet, the bits are transmitted LSB to MSB.
//! For this address, the first bit to be transmitted would be "0", the LSB of
//! "AC", and the last bit to be transmitted would be "1", the MSB of "80".
//!
//! \return None.
//
//*****************************************************************************
void
EthernetMACAddrSet(unsigned long ulBase, unsigned char *pucMACAddr)
{
unsigned long ulTemp;
unsigned char *pucTemp = (unsigned char *)&ulTemp;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT(pucMACAddr != 0);
//
// Program the MAC Address into the device. The first four bytes of the
// MAC Address are placed into the IA0 register. The remaining two bytes
// of the MAC address are placed into the IA1 register.
//
pucTemp[0] = pucMACAddr[0];
pucTemp[1] = pucMACAddr[1];
pucTemp[2] = pucMACAddr[2];
pucTemp[3] = pucMACAddr[3];
HWREG(ulBase + MAC_O_IA0) = ulTemp;
ulTemp = 0;
pucTemp[0] = pucMACAddr[4];
pucTemp[1] = pucMACAddr[5];
HWREG(ulBase + MAC_O_IA1) = ulTemp;
}
//*****************************************************************************
//
//! Gets the MAC Address of the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//! \param pucMACAddr is the pointer to the location in which to store the
//! array of MAC-48 Address Octets.
//!
//! This function will read the currently programed MAC address into the
//! \e pucMACAddr buffer.
//!
//! \sa Refer to \e EthernetMACSet API description for more details about
//! the MAC address format.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetMACAddrGet(unsigned long ulBase, unsigned char *pucMACAddr)
{
unsigned long ulTemp;
unsigned char *pucTemp = (unsigned char *)&ulTemp;
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
ASSERT(pucMACAddr != 0);
//
// Read the MAC address from the device. The first four bytes of the
// MAC address are read from the IA0 register. The remaining two bytes
// of the MAC addres
//
ulTemp = HWREG(ulBase + MAC_O_IA0);
pucMACAddr[0] = pucTemp[0];
pucMACAddr[1] = pucTemp[1];
pucMACAddr[2] = pucTemp[2];
pucMACAddr[3] = pucTemp[3];
ulTemp = HWREG(ulBase + MAC_O_IA1);
pucMACAddr[4] = pucTemp[0];
pucMACAddr[5] = pucTemp[1];
}
//*****************************************************************************
//
//! Enables the Ethernet Controller for normal operation.
//!
//! \param ulBase is the base address of the controller.
//!
//! Once the Ethernet Controller has been configured using the
//! \e EthernetConfigSet function and the MAC address has been programmed using
//! the \e EthernetMACAddrSet function, this API function can be called to
//! enable the controller for normal operation.
//!
//! This function will enable the controller's transmitter and receiver, and
//! will reset the receive FIFO.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetEnable(unsigned long ulBase)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Reset the receive FIFO.
//
HWREG(ulBase + MAC_O_RCTL) |= (MAC_RCTL_RSTFIFO);
//
// Enable the Ethernet receiver.
//
HWREG(ulBase + MAC_O_RCTL) |= (MAC_RCTL_RXEN);
//
// Enable Ethernet transmitter.
//
HWREG(ulBase + MAC_O_TCTL) |= (MAC_TCTL_TXEN);
//
// Reset the receive FIFO again, after the receiver has been enabled.
//
HWREG(ulBase + MAC_O_RCTL) |= (MAC_RCTL_RSTFIFO);
}
//*****************************************************************************
//
//! Disables the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//!
//! When terminating operations on the Ethernet interface, this function should
//! be called. This function will disable the transmitter and receiver, and
//! will clear out the receive FIFO.
//!
//! \return None.
//
//*****************************************************************************
void
EthernetDisable(unsigned long ulBase)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
//
// Reset the receive FIFO.
//
HWREG(ulBase + MAC_O_RCTL) |= (MAC_RCTL_RSTFIFO);
//
// Disable the Ethernet transmitter.
//
HWREG(ulBase + MAC_O_TCTL) &= ~(MAC_TCTL_TXEN);
//
// Disable the Ethernet receiver.
//
HWREG(ulBase + MAC_O_RCTL) &= ~(MAC_RCTL_RXEN);
//
// Reset the receive FIFO again, after the receiver has been disabled.
//
HWREG(ulBase + MAC_O_RCTL) |= (MAC_RCTL_RSTFIFO);
}
//*****************************************************************************
//
//! Check for packet available from the Ethernet Controller.
//!
//! \param ulBase is the base address of the controller.
//!
//! The Ethernet Controller provides a register that contains the number of
//! packets available in the receive FIFO. When the last bytes of a packet
//! successfully received (i.e. the frame check sequence bytes), the packet
//! count is incremented. Once the packet has been fully read (including the
//! frame check sequence bytes) from the FIFO, the packet count will be
//! decremented.
//!
//! \return This function will return \b true if there are one or more
//! packets available in the receive FIFO, including the current packet being
//! read. Otherwise, this function will return \b false.
//
//*****************************************************************************
tBoolean
EthernetPacketAvail(unsigned long ulBase)
{
//
// Check the arguments.
//
ASSERT(ulBase == ETH_BASE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -