|
|
@@ -0,0 +1,4979 @@
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// emac.c - Driver for the Integrated Ethernet Controller
|
|
|
+//
|
|
|
+// Copyright (c) 2013-2017 Texas Instruments Incorporated. All rights reserved.
|
|
|
+// Software License Agreement
|
|
|
+//
|
|
|
+// Redistribution and use in source and binary forms, with or without
|
|
|
+// modification, are permitted provided that the following conditions
|
|
|
+// are met:
|
|
|
+//
|
|
|
+// Redistributions of source code must retain the above copyright
|
|
|
+// notice, this list of conditions and the following disclaimer.
|
|
|
+//
|
|
|
+// Redistributions in binary form must reproduce the above copyright
|
|
|
+// notice, this list of conditions and the following disclaimer in the
|
|
|
+// documentation and/or other materials provided with the
|
|
|
+// distribution.
|
|
|
+//
|
|
|
+// Neither the name of Texas Instruments Incorporated nor the names of
|
|
|
+// its contributors may be used to endorse or promote products derived
|
|
|
+// from this software without specific prior written permission.
|
|
|
+//
|
|
|
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! \addtogroup emac_api
|
|
|
+//! @{
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+
|
|
|
+#include <ti/devices/msp432e4/inc/msp432e411y.h>
|
|
|
+#include "types.h"
|
|
|
+#include <stdbool.h>
|
|
|
+#include <stdint.h>
|
|
|
+#include "inc/hw_emac.h"
|
|
|
+#include "debug.h"
|
|
|
+#include "emac.h"
|
|
|
+#include "sysctl.h"
|
|
|
+#include "interrupt.h"
|
|
|
+#include "sw_crc.h"
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined defines used in parameter validity checks.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined valid configuration flags.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define VALID_CONFIG_FLAGS (EMAC_CONFIG_USE_MACADDR1 | \
|
|
|
+ EMAC_CONFIG_SA_INSERT | \
|
|
|
+ EMAC_CONFIG_SA_REPLACE | \
|
|
|
+ EMAC_CONFIG_2K_PACKETS | \
|
|
|
+ EMAC_CONFIG_STRIP_CRC | \
|
|
|
+ EMAC_CONFIG_JABBER_DISABLE | \
|
|
|
+ EMAC_CONFIG_JUMBO_ENABLE | \
|
|
|
+ EMAC_CONFIG_IF_GAP_MASK | \
|
|
|
+ EMAC_CONFIG_CS_DISABLE | \
|
|
|
+ EMAC_CONFIG_100MBPS | \
|
|
|
+ EMAC_CONFIG_RX_OWN_DISABLE | \
|
|
|
+ EMAC_CONFIG_LOOPBACK | \
|
|
|
+ EMAC_CONFIG_FULL_DUPLEX | \
|
|
|
+ EMAC_CONFIG_CHECKSUM_OFFLOAD | \
|
|
|
+ EMAC_CONFIG_RETRY_DISABLE | \
|
|
|
+ EMAC_CONFIG_AUTO_CRC_STRIPPING | \
|
|
|
+ EMAC_CONFIG_BO_MASK | \
|
|
|
+ EMAC_CONFIG_DEFERRAL_CHK_ENABLE | \
|
|
|
+ EMAC_CONFIG_PREAMBLE_MASK)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined valid frame filter flags.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define VALID_FRMFILTER_FLAGS (EMAC_FRMFILTER_RX_ALL | \
|
|
|
+ EMAC_FRMFILTER_VLAN | \
|
|
|
+ EMAC_FRMFILTER_HASH_AND_PERFECT | \
|
|
|
+ EMAC_FRMFILTER_SADDR | \
|
|
|
+ EMAC_FRMFILTER_INV_SADDR | \
|
|
|
+ EMAC_FRMFILTER_PASS_NO_PAUSE | \
|
|
|
+ EMAC_FRMFILTER_PASS_ALL_CTRL | \
|
|
|
+ EMAC_FRMFILTER_PASS_ADDR_CTRL | \
|
|
|
+ EMAC_FRMFILTER_BROADCAST | \
|
|
|
+ EMAC_FRMFILTER_PASS_MULTICAST | \
|
|
|
+ EMAC_FRMFILTER_INV_DADDR | \
|
|
|
+ EMAC_FRMFILTER_HASH_MULTICAST | \
|
|
|
+ EMAC_FRMFILTER_HASH_UNICAST | \
|
|
|
+ EMAC_FRMFILTER_PROMISCUOUS)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined valid maskable interrupts.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define EMAC_MASKABLE_INTS (EMAC_INT_EARLY_RECEIVE | \
|
|
|
+ EMAC_INT_BUS_ERROR | \
|
|
|
+ EMAC_INT_EARLY_TRANSMIT | \
|
|
|
+ EMAC_INT_RX_WATCHDOG | \
|
|
|
+ EMAC_INT_RX_STOPPED | \
|
|
|
+ EMAC_INT_RX_NO_BUFFER | \
|
|
|
+ EMAC_INT_RECEIVE | \
|
|
|
+ EMAC_INT_TX_UNDERFLOW | \
|
|
|
+ EMAC_INT_RX_OVERFLOW | \
|
|
|
+ EMAC_INT_TX_JABBER | \
|
|
|
+ EMAC_INT_TX_NO_BUFFER | \
|
|
|
+ EMAC_INT_TX_STOPPED | \
|
|
|
+ EMAC_INT_TRANSMIT | \
|
|
|
+ EMAC_INT_NORMAL_INT | \
|
|
|
+ EMAC_INT_ABNORMAL_INT | \
|
|
|
+ EMAC_INT_PHY)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined valid normal interrupts.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define EMAC_NORMAL_INTS (EMAC_INT_TRANSMIT | \
|
|
|
+ EMAC_INT_RECEIVE | \
|
|
|
+ EMAC_INT_EARLY_RECEIVE | \
|
|
|
+ EMAC_INT_TX_NO_BUFFER)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Combined valid abnormal interrupts.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define EMAC_ABNORMAL_INTS (EMAC_INT_TX_STOPPED | \
|
|
|
+ EMAC_INT_TX_JABBER | \
|
|
|
+ EMAC_INT_RX_OVERFLOW | \
|
|
|
+ EMAC_INT_TX_UNDERFLOW | \
|
|
|
+ EMAC_INT_RX_NO_BUFFER | \
|
|
|
+ EMAC_INT_RX_STOPPED | \
|
|
|
+ EMAC_INT_RX_WATCHDOG | \
|
|
|
+ EMAC_INT_EARLY_TRANSMIT | \
|
|
|
+ EMAC_INT_BUS_ERROR)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Interrupt sources reported via the DMARIS register but which are not
|
|
|
+// masked (or enabled) via the DMAIM register.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define EMAC_NON_MASKED_INTS (EMAC_DMARIS_LPI | \
|
|
|
+ EMAC_DMARIS_TT | \
|
|
|
+ EMAC_DMARIS_PMT | \
|
|
|
+ EMAC_DMARIS_MMC)
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// The number of MAC addresses the module can store for filtering purposes.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define NUM_MAC_ADDR 4
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Macros aiding access to the MAC address registers.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define MAC_ADDR_OFFSET (EMAC_O_ADDR1L - EMAC_O_ADDR0L)
|
|
|
+#define EMAC_O_ADDRL(n) (EMAC_O_ADDR0L + (MAC_ADDR_OFFSET * (n)))
|
|
|
+#define EMAC_O_ADDRH(n) (EMAC_O_ADDR0H + (MAC_ADDR_OFFSET * (n)))
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// A structure used to help in choosing the correct clock divisor for the MII
|
|
|
+// based on the current system clock rate.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+static const struct
|
|
|
+{
|
|
|
+ uint32_t ui32SysClockMax;
|
|
|
+ uint32_t ui32Divisor;
|
|
|
+}
|
|
|
+g_pi16MIIClockDiv[] =
|
|
|
+{
|
|
|
+ { 64000000, EMAC_MIIADDR_CR_35_60 },
|
|
|
+ { 104000000, EMAC_MIIADDR_CR_60_100 },
|
|
|
+ { 150000000, EMAC_MIIADDR_CR_100_150 }
|
|
|
+};
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// The number of clock divisors in the above table.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define NUM_CLOCK_DIVISORS (sizeof(g_pi16MIIClockDiv) / \
|
|
|
+ sizeof(g_pi16MIIClockDiv[0]))
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// The define for accessing PHY registers in the MMD address space.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+#define DEV_ADDR(x) ((x & 0xF000) >> 12)
|
|
|
+#define REG_ADDR(x) ((x & 0x0FFF))
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Initializes the Ethernet MAC and sets bus-related DMA parameters.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param ui32SysClk is the current system clock frequency in Hertz.
|
|
|
+//! \param ui32BusConfig defines the bus operating mode for the Ethernet MAC
|
|
|
+//! DMA controller.
|
|
|
+//! \param ui32RxBurst is the maximum receive burst size in words.
|
|
|
+//! \param ui32TxBurst is the maximum transmit burst size in words.
|
|
|
+//! \param ui32DescSkipSize is the number of 32-bit words to skip between
|
|
|
+//! two unchained DMA descriptors. Values in the range 0 to 31 are valid.
|
|
|
+//!
|
|
|
+//! This function sets bus-related parameters for the Ethernet MAC DMA
|
|
|
+//! engines. It must be called after EMACPHYConfigSet() and called again
|
|
|
+//! after any subsequent call to EMACPHYConfigSet().
|
|
|
+//!
|
|
|
+//! The \e ui32BusConfig parameter is the logical OR of various fields. The
|
|
|
+//! first sets the DMA channel priority weight:
|
|
|
+//!
|
|
|
+//! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_1
|
|
|
+//! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_2
|
|
|
+//! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_3
|
|
|
+//! - \b EMAC_BCONFIG_DMA_PRIO_WEIGHT_4
|
|
|
+//!
|
|
|
+//! The second field sets the receive and transmit priorities used when
|
|
|
+//! arbitrating between the Rx and Tx DMA. The priorities are Rx:Tx unless
|
|
|
+//! \b EMAC_BCONFIG_TX_PRIORITY is also specified, in which case they become
|
|
|
+//! Tx:Rx. The priority provided here is ignored if
|
|
|
+//! \b EMAC_BCONFIG_PRIORITY_FIXED is specified.
|
|
|
+//!
|
|
|
+//! - \b EMAC_BCONFIG_PRIORITY_1_1
|
|
|
+//! - \b EMAC_BCONFIG_PRIORITY_2_1
|
|
|
+//! - \b EMAC_BCONFIG_PRIORITY_3_1
|
|
|
+//! - \b EMAC_BCONFIG_PRIORITY_4_1
|
|
|
+//!
|
|
|
+//! The following additional flags may also be defined:
|
|
|
+//!
|
|
|
+//! - \b EMAC_BCONFIG_TX_PRIORITY indicates that the transmit DMA should be
|
|
|
+//! higher priority in all arbitration for the system-side bus. If this is not
|
|
|
+//! defined, the receive DMA has higher priority.
|
|
|
+//! - \b EMAC_BCONFIG_ADDR_ALIGNED works in tandem with
|
|
|
+//! \b EMAC_BCONFIG_FIXED_BURST to control address alignment of AHB bursts.
|
|
|
+//! When both flags are specified, all bursts are aligned to the start address
|
|
|
+//! least significant bits. If \b EMAC_BCONFIG_FIXED_BURST is not specified,
|
|
|
+//! the first burst is unaligned but subsequent bursts are aligned to the
|
|
|
+//! address.
|
|
|
+//! - \b EMAC_BCONFIG_ALT_DESCRIPTORS indicates that the DMA engine should
|
|
|
+//! use the alternate descriptor format as defined in type
|
|
|
+//! \b tEMACDMADescriptor. If absent, the basic descriptor type is used.
|
|
|
+//! Alternate descriptors are required if using IEEE 1588-2008 advanced
|
|
|
+//! timestamping, VLAN or TCP/UDP/ICMP CRC insertion features. Note that,
|
|
|
+//! for clarity, emac.h does not contain type definitions for the basic
|
|
|
+//! descriptor type. Please see the technical reference manual/datasheet
|
|
|
+//! for information on basic descriptor structures.
|
|
|
+//! - \b EMAC_BCONFIG_PRIORITY_FIXED indicates that a fixed priority scheme
|
|
|
+//! should be employed when arbitrating between the transmit and receive DMA
|
|
|
+//! for system-side bus access. In this case, the receive channel always has
|
|
|
+//! priority unless \b EMAC_BCONFIG_TX_PRIORITY is set, in which case the
|
|
|
+//! transmit channel has priority. If \b EMAC_BCONFIG_PRIORITY_FIXED is not
|
|
|
+//! specified, a weighted round-robin arbitration scheme is used with the
|
|
|
+//! weighting defined using \b EMAC_BCONFIG_PRIORITY_1_1,
|
|
|
+//! \b EMAC_BCONFIG_PRIORITY_2_1, \b EMAC_BCONFIG_PRIORITY_3_1 or
|
|
|
+//! \b EMAC_BCONFIG_PRIORITY_4_1, and \b EMAC_BCONFIG_TX_PRIORITY.
|
|
|
+//! - \b EMAC_BCONFIG_FIXED_BURST indicates that fixed burst transfers should
|
|
|
+//! be used.
|
|
|
+//! - \b EMAC_BCONFIG_MIXED_BURST indicates that the DMA engine should use
|
|
|
+//! mixed burst types depending on the length of data to be transferred
|
|
|
+//! across the system bus.
|
|
|
+//!
|
|
|
+//! The \e ui32RxBurst and \e ui32TxBurst parameters indicate the maximum
|
|
|
+//! number of words that the relevant DMA should transfer in a single
|
|
|
+//! transaction. Valid values are 1, 2, 4, 8, 16 and 32. Any other value
|
|
|
+//! results in undefined behavior.
|
|
|
+//!
|
|
|
+//! The \e ui32DescSkipSize parameter is used when the descriptor lists are
|
|
|
+//! using ring mode (where descriptors are contiguous in memory with the last
|
|
|
+//! descriptor marked with the \b END_OF_RING flag) rather than chained mode
|
|
|
+//! (where each descriptor includes a field that points to the next descriptor
|
|
|
+//! in the list). In ring mode, the hardware uses the \e ui32DescSkipSize to
|
|
|
+//! skip past any application-defined fields after the end of the hardware-
|
|
|
+//! defined descriptor fields. The parameter value indicates the number of
|
|
|
+//! 32-bit words to skip after the last field of the hardware-defined
|
|
|
+//! descriptor to get to the first field of the next descriptor. When using
|
|
|
+//! arrays of either the \b tEMACDMADescriptor or \b tEMACAltDMADescriptor
|
|
|
+//! types defined for this driver, \e ui32DescSkipSize must be set to 1 to skip
|
|
|
+//! the \e pvNext pointer added to the end of each of these structures.
|
|
|
+//! Applications may modify these structure definitions to include their own
|
|
|
+//! application-specific data and modify \e ui32DescSkipSize appropriately if
|
|
|
+//! desired.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACInit(uint32_t ui32Base, uint32_t ui32SysClk, uint32_t ui32BusConfig,
|
|
|
+ uint32_t ui32RxBurst, uint32_t ui32TxBurst, uint32_t ui32DescSkipSize)
|
|
|
+{
|
|
|
+ uint32_t ui32Val, ui32Div;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity checks.
|
|
|
+ //
|
|
|
+ ASSERT(ui32DescSkipSize < 32);
|
|
|
+ ASSERT(ui32TxBurst < (32 * 8));
|
|
|
+ ASSERT(ui32RxBurst < (32 * 8));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Make sure that the DMA software reset is clear before continuing.
|
|
|
+ //
|
|
|
+ while (HWREG(EMAC0_BASE + EMAC_O_DMABUSMOD) & EMAC_DMABUSMOD_SWR)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set common flags. Note that this driver assumes we are always using
|
|
|
+ // 8 word descriptors so we need to OR in EMAC_DMABUSMOD_ATDS here.
|
|
|
+ //
|
|
|
+ ui32Val = (ui32BusConfig | (ui32DescSkipSize << EMAC_DMABUSMOD_DSL_S) |
|
|
|
+ EMAC_DMABUSMOD_ATDS);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Do we need to use the 8X burst length multiplier?
|
|
|
+ //
|
|
|
+ if ((ui32TxBurst > 32) || (ui32RxBurst > 32))
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Divide both burst lengths by 8 and set the 8X burst length
|
|
|
+ // multiplier.
|
|
|
+ //
|
|
|
+ ui32Val |= EMAC_DMABUSMOD_8XPBL;
|
|
|
+ ui32TxBurst >>= 3;
|
|
|
+ ui32RxBurst >>= 3;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Sanity check - neither burst length should have become zero. If
|
|
|
+ // they did, this indicates that the values passed are invalid.
|
|
|
+ //
|
|
|
+ ASSERT(ui32RxBurst);
|
|
|
+ ASSERT(ui32TxBurst);
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Are the receive and transmit burst lengths the same?
|
|
|
+ //
|
|
|
+ if (ui32RxBurst == ui32TxBurst)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Yes - set up to use a single burst length.
|
|
|
+ //
|
|
|
+ ui32Val |= (ui32TxBurst << EMAC_DMABUSMOD_PBL_S);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // No - we need to use separate burst lengths for each.
|
|
|
+ //
|
|
|
+ ui32Val |= (EMAC_DMABUSMOD_USP |
|
|
|
+ (ui32TxBurst << EMAC_DMABUSMOD_PBL_S) |
|
|
|
+ (ui32RxBurst << EMAC_DMABUSMOD_RPBL_S));
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Finally, write the bus mode register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMABUSMOD) = ui32Val;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Default the MII CSR clock divider based on the fastest system clock.
|
|
|
+ //
|
|
|
+ ui32Div = g_pi16MIIClockDiv[NUM_CLOCK_DIVISORS - 1].ui32Divisor;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Find the MII CSR clock divider to use based on the current system clock.
|
|
|
+ //
|
|
|
+ for (ui32Val = 0; ui32Val < NUM_CLOCK_DIVISORS; ui32Val++)
|
|
|
+ {
|
|
|
+ if (ui32SysClk <= g_pi16MIIClockDiv[ui32Val].ui32SysClockMax)
|
|
|
+ {
|
|
|
+ ui32Div = g_pi16MIIClockDiv[ui32Val].ui32Divisor;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the MII CSR clock speed.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_MIIADDR) = ((HWREG(ui32Base + EMAC_O_MIIADDR) &
|
|
|
+ ~EMAC_MIIADDR_CR_M) | ui32Div);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable all the MMC interrupts as these are enabled by default at reset.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_MMCRXIM) = 0xFFFFFFFF;
|
|
|
+ HWREG(ui32Base + EMAC_O_MMCTXIM) = 0xFFFFFFFF;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Resets the Ethernet MAC.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! This function performs a reset of the Ethernet MAC by resetting all logic
|
|
|
+//! and returning all registers to their default values. The function returns
|
|
|
+//! only after the hardware indicates that the reset has completed.
|
|
|
+//!
|
|
|
+//! \note To ensure that the reset completes, the selected PHY clock must be
|
|
|
+//! enabled when this function is called. If the PHY clock is absent, this
|
|
|
+//! function does not return.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACReset(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Reset the Ethernet MAC.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMABUSMOD) |= EMAC_DMABUSMOD_SWR;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for the reset to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_DMABUSMOD) & EMAC_DMABUSMOD_SWR)
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Selects the Ethernet PHY in use.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param ui32Config selects the PHY in use and, when using the internal
|
|
|
+//! PHY, allows various various PHY parameters to be configured.
|
|
|
+//!
|
|
|
+//! This function must be called prior to EMACInit() and EMACConfigSet() to
|
|
|
+//! select the Ethernet PHY to be used. If the internal PHY is selected, the
|
|
|
+//! function also allows configuration of various PHY parameters. Note that
|
|
|
+//! the Ethernet MAC is reset during this function call because parameters used
|
|
|
+//! by this function are latched by the hardware only on a MAC reset. The call
|
|
|
+//! sequence to select and configure the PHY, therefore, must be as follows:
|
|
|
+//!
|
|
|
+//! \verbatim
|
|
|
+//! // Enable and reset the MAC.
|
|
|
+//! SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
|
|
|
+//! SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
|
|
|
+//! if(<using internal PHY>)
|
|
|
+//! {
|
|
|
+//! // Enable and reset the internal PHY.
|
|
|
+//! SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
|
|
|
+//! SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
|
|
|
+//! }
|
|
|
+//!
|
|
|
+//! // Ensure the MAC is completed its reset.
|
|
|
+//! while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
|
|
|
+//! {
|
|
|
+//! }
|
|
|
+//!
|
|
|
+//! // Set the PHY type and configuration options.
|
|
|
+//! EMACPHYConfigSet(EMAC0_BASE, <config>);
|
|
|
+//!
|
|
|
+//! // Initialize and configure the MAC.
|
|
|
+//! EMACInit(EMAC0_BASE, <system clock rate>, <bus config>,
|
|
|
+//! <Rx burst size>, <Tx burst size>, <desc skip>);
|
|
|
+//! EMACConfigSet(EMAC0_BASE, <parameters>);
|
|
|
+//! \endverbatim
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter must specify one of the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PHY_TYPE_INTERNAL selects the internal Ethernet PHY.
|
|
|
+//! - \b EMAC_PHY_TYPE_EXTERNAL_MII selects an external PHY connected via the
|
|
|
+//! MII interface.
|
|
|
+//! - \b EMAC_PHY_TYPE_EXTERNAL_RMII selects an external PHY connected via the
|
|
|
+//! RMII interface.
|
|
|
+//!
|
|
|
+//! If \b EMAC_PHY_TYPE_INTERNAL is selected, the following flags may be ORed
|
|
|
+//! into \e ui32Config to control various PHY features and modes. These flags
|
|
|
+//! are ignored if an external PHY is selected.
|
|
|
+//!
|
|
|
+//! - \b EMAC_PHY_INT_NIB_TXERR_DET_DIS disables odd nibble transmit error
|
|
|
+//! detection (sets the default value of PHY register MR10, bit 1).
|
|
|
+//! - \b EMAC_PHY_INT_RX_ER_DURING_IDLE enables receive error detection during
|
|
|
+//! idle (sets the default value of PHY register MR10, bit 2).
|
|
|
+//! - \b EMAC_PHY_INT_ISOLATE_MII_LLOSS ties the MII outputs low if no link is
|
|
|
+//! established in 100B-T and full duplex modes (sets the default value of PHY
|
|
|
+//! register MR10, bit 3).
|
|
|
+//! - \b EMAC_PHY_INT_LINK_LOSS_RECOVERY enables link loss recovery (sets the
|
|
|
+//! default value of PHY register MR9, bit 7).
|
|
|
+//! - \b EMAC_PHY_INT_TDRRUN enables execution of the TDR procedure after a link
|
|
|
+//! down event (sets the default value of PHY register MR9, bit 8).
|
|
|
+//! - \b EMAC_PHY_INT_LD_ON_RX_ERR_COUNT enables link down if the receiver
|
|
|
+//! error count reaches 32 within a 10-us interval (sets the default value of
|
|
|
+//! PHY register MR11 bit 3).
|
|
|
+//! - \b EMAC_PHY_INT_LD_ON_MTL3_ERR_COUNT enables link down if the MTL3 error
|
|
|
+//! count reaches 20 in a 10 us-interval (sets the default value of PHY register
|
|
|
+//! MR11 bit 2).
|
|
|
+//! - \b EMAC_PHY_INT_LD_ON_LOW_SNR enables link down if the low SNR threshold
|
|
|
+//! is crossed 20 times in a 10 us-interval (sets the default value of PHY
|
|
|
+//! register MR11 bit 1).
|
|
|
+//! - \b EMAC_PHY_INT_LD_ON_SIGNAL_ENERGY enables link down if energy detector
|
|
|
+//! indicates Energy Loss (sets the default value of PHY register MR11 bit 0).
|
|
|
+//! - \b EMAC_PHY_INT_POLARITY_SWAP inverts the polarity on both TPTD and TPRD
|
|
|
+//! pairs (sets the default value of PHY register MR11 bit 5).
|
|
|
+//! - \b EMAC_PHY_INT_MDI_SWAP swaps the MDI pairs putting receive on the TPTD
|
|
|
+//! pair and transmit on TPRD (sets the default value of PHY register MR11 bit
|
|
|
+//! 6).
|
|
|
+//! - \b EMAC_PHY_INT_ROBUST_MDIX enables robust auto MDI-X resolution (sets the
|
|
|
+//! default value of PHY register MR9 bit 5).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_MDIX enables fast auto-MDI/MDIX resolution (sets the
|
|
|
+//! default value of PHY register MR9 bit 6).
|
|
|
+//! - \b EMAC_PHY_INT_MDIX_EN enables auto-MDI/MDIX crossover (sets the
|
|
|
+//! default value of PHY register MR9 bit 14).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_RXDV_DETECT enables fast RXDV detection (set the
|
|
|
+//! default value of PHY register MR9 bit 1).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_L_UP_DETECT enables fast link-up time during parallel
|
|
|
+//! detection (sets the default value of PHY register MR10 bit 6)
|
|
|
+//! - \b EMAC_PHY_INT_EXT_FULL_DUPLEX forces full-duplex while working with a
|
|
|
+//! link partner in forced 100B-TX (sets the default value of PHY register
|
|
|
+//! MR10 bit 5).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_AN_80_50_35 enables fast auto-negotiation using
|
|
|
+//! break link, link fail inhibit and wait timers set to 80, 50 and 35
|
|
|
+//! respectively (sets the default value of PHY register MR9 bits [4:2] to
|
|
|
+//! 3b100).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_AN_120_75_50 enables fast auto-negotiation using
|
|
|
+//! break link, link fail inhibit and wait timers set to 120, 75 and 50
|
|
|
+//! respectively (sets the default value of PHY register MR9 bits [4:2] to
|
|
|
+//! 3b101).
|
|
|
+//! - \b EMAC_PHY_INT_FAST_AN_140_150_100 enables fast auto-negotiation using
|
|
|
+//! break link, link fail inhibit and wait timers set to 140, 150 and 100
|
|
|
+//! respectively (sets the default value of PHY register MR9 bits [4:2] to
|
|
|
+//! 3b110).
|
|
|
+//! - \b EMAC_PHY_FORCE_10B_T_HALF_DUPLEX disables auto-negotiation and forces
|
|
|
+//! operation in 10Base-T, half duplex mode (sets the default value of PHY
|
|
|
+//! register MR9 bits [13:11] to 3b000).
|
|
|
+//! - \b EMAC_PHY_FORCE_10B_T_FULL_DUPLEX disables auto-negotiation and forces
|
|
|
+//! operation in 10Base-T, full duplex mode (sets the default value of PHY
|
|
|
+//! register MR9 bits [13:11] to 3b001).
|
|
|
+//! - \b EMAC_PHY_FORCE_100B_T_HALF_DUPLEX disables auto-negotiation and forces
|
|
|
+//! operation in 100Base-T, half duplex mode (sets the default value of PHY
|
|
|
+//! register MR9 bits [13:11] to 3b010).
|
|
|
+//! - \b EMAC_PHY_FORCE_100B_T_FULL_DUPLEX disables auto-negotiation and forces
|
|
|
+//! operation in 100Base-T, full duplex mode (sets the default value of PHY
|
|
|
+//! register MR9 bits [13:11] to 3b011).
|
|
|
+//! - \b EMAC_PHY_AN_10B_T_HALF_DUPLEX enables auto-negotiation and advertises
|
|
|
+//! 10Base-T, half duplex mode (sets the default value of PHY register MR9 bits
|
|
|
+//! [13:11] to 3b100).
|
|
|
+//! - \b EMAC_PHY_AN_10B_T_FULL_DUPLEX enables auto-negotiation and advertises
|
|
|
+//! 10Base-T half or full duplex modes (sets the default value of PHY register
|
|
|
+//! MR9 bits [13:11] to 3b101).
|
|
|
+//! - \b EMAC_PHY_AN_100B_T_HALF_DUPLEX enables auto-negotiation and advertises
|
|
|
+//! 10Base-T half or full duplex, and 100Base-T half duplex modes (sets the
|
|
|
+//! default value of PHY register MR9 bits [13:11] to 3b110).
|
|
|
+//! - \b EMAC_PHY_AN_100B_T_FULL_DUPLEX enables auto-negotiation and advertises
|
|
|
+//! 10Base-T half or full duplex, and 100Base-T half or full duplex modes (sets
|
|
|
+//! the default value of PHY register MR9 bits [13:11] to 3b111).
|
|
|
+//! - \b EMAC_PHY_INT_HOLD prevents the PHY from transmitting energy on the
|
|
|
+//! line.
|
|
|
+//!
|
|
|
+//! As a side effect of this function, the Ethernet MAC is reset so any
|
|
|
+//! previous MAC configuration is lost.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYConfigSet(uint32_t ui32Base, uint32_t ui32Config)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Write the Ethernet PHY configuration to the peripheral configuration
|
|
|
+ // register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PC) = ui32Config;
|
|
|
+
|
|
|
+ //
|
|
|
+ // If using the internal PHY, reset it to ensure that new configuration is
|
|
|
+ // latched there.
|
|
|
+ //
|
|
|
+ if ((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_INTERNAL)
|
|
|
+ {
|
|
|
+ SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
|
|
|
+ while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0))
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Wait for the PHY reset to complete.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Delay a bit longer to ensure that the PHY reset has completed.
|
|
|
+ //
|
|
|
+ SysCtlDelay(10000);
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // If using an external RMII PHY, we must set 2 bits in the Ethernet MAC
|
|
|
+ // Clock Configuration Register.
|
|
|
+ //
|
|
|
+ if ((ui32Config & EMAC_PHY_TYPE_MASK) == EMAC_PHY_TYPE_EXTERNAL_RMII)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Select and enable the external clock from the RMII PHY.
|
|
|
+ //
|
|
|
+ HWREG(EMAC0_BASE + EMAC_O_CC) |= EMAC_CC_CLKEN;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Disable the external clock.
|
|
|
+ //
|
|
|
+ HWREG(EMAC0_BASE + EMAC_O_CC) &= ~EMAC_CC_CLKEN;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Reset the MAC regardless of whether the PHY connection changed or not.
|
|
|
+ //
|
|
|
+ EMACReset(EMAC0_BASE);
|
|
|
+
|
|
|
+ SysCtlDelay(1000);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Configures basic Ethernet MAC operation parameters.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param ui32Config provides various flags and values configuring the MAC.
|
|
|
+//! \param ui32ModeFlags provides configuration relating to the transmit and
|
|
|
+//! receive DMA engines.
|
|
|
+//! \param ui32RxMaxFrameSize sets the maximum receive frame size above which
|
|
|
+//! an error is reported.
|
|
|
+//!
|
|
|
+//! This function is called to configure basic operating parameters for the
|
|
|
+//! MAC and its DMA engines.
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter is the logical OR of various fields and
|
|
|
+//! flags. The first field determines which MAC address is used during
|
|
|
+//! insertion or replacement for all transmitted frames. Valid options are
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_USE_MACADDR1 and
|
|
|
+//! - \b EMAC_CONFIG_USE_MACADDR0
|
|
|
+//!
|
|
|
+//! The interframe gap between transmitted frames is controlled using one of
|
|
|
+//! the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_96BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_88BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_80BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_72BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_64BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_56BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_48BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_40BITS
|
|
|
+//!
|
|
|
+//! The number of bytes of preamble added to the beginning of every transmitted
|
|
|
+//! frame is selected using one of the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_7BYTE_PREAMBLE
|
|
|
+//! - \b EMAC_CONFIG_5BYTE_PREAMBLE
|
|
|
+//! - \b EMAC_CONFIG_3BYTE_PREAMBLE
|
|
|
+//!
|
|
|
+//! The back-off limit determines the range of the random time that the MAC
|
|
|
+//! delays after a collision and before attempting to retransmit a frame. One
|
|
|
+//! of the following values must be used to select this limit. In each case,
|
|
|
+//! the retransmission delay in terms of 512 bit time slots, is the lower of
|
|
|
+//! (2 ** N) and a random number between 0 and the selected backoff-limit.
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_1024
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_256
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_16
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_2
|
|
|
+//!
|
|
|
+//! Control over insertion or replacement of the source address in all
|
|
|
+//! transmitted frames is provided by using one of the following fields:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_SA_INSERT causes the MAC address (0 or 1 depending
|
|
|
+//! on whether \b EMAC_CONFIG_USE_MACADDR0 or \b EMAC_CONFIG_USE_MACADDR1
|
|
|
+//! was specified) to be inserted into all transmitted frames.
|
|
|
+//! - \b EMAC_CONFIG_SA_REPLACE causes the MAC address to be replaced with
|
|
|
+//! the selected address in all transmitted frames.
|
|
|
+//! - \b EMAC_CONFIG_SA_FROM_DESCRIPTOR causes control of source address
|
|
|
+//! insertion or deletion to be controlled by fields in the DMA transmit
|
|
|
+//! descriptor, allowing control on a frame-by-frame basis.
|
|
|
+//!
|
|
|
+//! Whether the interface attempts to operate in full- or half-duplex mode is
|
|
|
+//! controlled by one of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_FULL_DUPLEX
|
|
|
+//! - \b EMAC_CONFIG_HALF_DUPLEX
|
|
|
+//!
|
|
|
+//! The following additional flags may also be specified:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_2K_PACKETS enables IEEE802.3as support for 2K packets.
|
|
|
+//! When specified, the MAC considers all frames up to 2000 bytes in length as
|
|
|
+//! normal packets. When \b EMAC_CONFIG_JUMBO_ENABLE is not specified, all
|
|
|
+//! frames larger than 2000 bytes are treated as Giant frames. This flag is
|
|
|
+//! ignored if \b EMAC_CONFIG_JUMBO_ENABLE is specified.
|
|
|
+//! - \b EMAC_CONFIG_STRIP_CRC causes the 4-byte CRC of all Ethernet type
|
|
|
+//! frames to be stripped and dropped before the frame is forwarded to the
|
|
|
+//! application.
|
|
|
+//! - \b EMAC_CONFIG_JABBER_DISABLE disables the jabber timer on the
|
|
|
+//! transmitter and enables frames of up to 16384 bytes to be transmitted. If
|
|
|
+//! this flag is absent, the MAC does not allow more than 2048 (or 10240 if
|
|
|
+//! \b EMAC_CONFIG_JUMBO_ENABLE is specified) bytes to be sent in any one
|
|
|
+//! frame.
|
|
|
+//! - \b EMAC_CONFIG_JUMBO_ENABLE enables Jumbo Frames, allowing frames of
|
|
|
+//! up to 9018 (or 9022 if using VLAN tagging) to be handled without reporting
|
|
|
+//! giant frame errors.
|
|
|
+//! - \b EMAC_CONFIG_100MBPS forces the MAC to communicate with the PHY using
|
|
|
+//! 100Mbps signaling. If this option is not specified, the MAC uses 10Mbps
|
|
|
+//! signaling. This speed setting is important when using an external RMII
|
|
|
+//! PHY where the selected rate must match the PHY's setting which may have
|
|
|
+//! been made as a result of auto-negotiation. When using the internal PHY
|
|
|
+//! or an external MII PHY, the signaling rate is controlled by the PHY-
|
|
|
+//! provided transmit and receive clocks.
|
|
|
+//! - \b EMAC_CONFIG_CS_DISABLE disables Carrier Sense during transmission
|
|
|
+//! when operating in half-duplex mode.
|
|
|
+//! - \b EMAC_CONFIG_RX_OWN_DISABLE disables reception of transmitted frames
|
|
|
+//! when operating in half-duplex mode.
|
|
|
+//! - \b EMAC_CONFIG_LOOPBACK enables internal loopback.
|
|
|
+//! - \b EMAC_CONFIG_CHECKSUM_OFFLOAD enables IPv4 header checksum checking
|
|
|
+//! and IPv4 or IPv6 TCP, UPD or ICMP payload checksum checking. The results
|
|
|
+//! of the checksum calculations are reported via status fields in the DMA
|
|
|
+//! receive descriptors.
|
|
|
+//! - \b EMAC_CONFIG_RETRY_DISABLE disables retransmission in cases where
|
|
|
+//! half-duplex mode is in use and a collision occurs. This condition causes
|
|
|
+//! the current frame to be ignored and a frame abort to be reported in the
|
|
|
+//! transmit frame status.
|
|
|
+//! - \b EMAC_CONFIG_AUTO_CRC_STRIPPING strips the last 4 bytes (frame check
|
|
|
+//! sequence) from all Ether type frames before forwarding the frames to the
|
|
|
+//! application.
|
|
|
+//! - \b EMAC_CONFIG_DEFERRAL_CHK_ENABLE enables transmit deferral checking
|
|
|
+//! in half-duplex mode. When enabled, the transmitter reports an error if it
|
|
|
+//! is unable to transmit a frame for more than 24288 bit times (or 155680
|
|
|
+//! bit times in Jumbo frame mode) due to an active carrier sense signal on
|
|
|
+//! the MII.
|
|
|
+//!
|
|
|
+//! The \e ui32ModeFlags parameter sets operating parameters related to the
|
|
|
+//! internal MAC FIFOs. It comprises a logical OR of the following fields.
|
|
|
+//! The first selects the transmit FIFO threshold. Transmission of a frame
|
|
|
+//! begins when this amount of data or a full frame exists in the transmit
|
|
|
+//! FIFO. This field is ignored if \b EMAC_MODE_TX_STORE_FORWARD is
|
|
|
+//! included. One of the following must be specified:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_16_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_24_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_32_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_40_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_64_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_128_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_192_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_256_BYTES
|
|
|
+//!
|
|
|
+//! The second field controls the receive FIFO threshold. DMA transfers of
|
|
|
+//! received data begin either when the receive FIFO contains a full frame
|
|
|
+//! or this number of bytes. This field is ignored if
|
|
|
+//! \b EMAC_MODE_RX_STORE_FORWARD is included. One of the following must be
|
|
|
+//! specified:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_64_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_32_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_96_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_128_BYTES
|
|
|
+//!
|
|
|
+//! The following additional flags may be specified:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_KEEP_BAD_CRC causes frames with TCP/IP checksum errors
|
|
|
+//! to be forwarded to the application if those frames do not have any errors
|
|
|
+//! (including FCS errors) in the Ethernet framing. In these cases, the frames
|
|
|
+//! have errors only in the payload. If this flag is not specified, all frames
|
|
|
+//! with any detected error are discarded unless \b EMAC_MODE_RX_ERROR_FRAMES
|
|
|
+//! is also specified.
|
|
|
+//! - \b EMAC_MODE_RX_STORE_FORWARD causes the receive DMA to read frames
|
|
|
+//! from the FIFO only after the complete frame has been written to it. If
|
|
|
+//! this mode is enabled, the receive threshold is ignored.
|
|
|
+//! - \b EMAC_MODE_RX_FLUSH_DISABLE disables the flushing of received frames
|
|
|
+//! in cases where receive descriptors or buffers are unavailable.
|
|
|
+//! - \b EMAC_MODE_TX_STORE_FORWARD causes the transmitter to start
|
|
|
+//! transmitting a frame only after the whole frame has been written to the
|
|
|
+//! transmit FIFO. If this mode is enabled, the transmit threshold is ignored.
|
|
|
+//! - \b EMAC_MODE_RX_ERROR_FRAMES causes all frames other than runt error
|
|
|
+//! frames to be forwarded to the receive DMA regardless of any errors detected
|
|
|
+//! in the frames.
|
|
|
+//! - \b EMAC_MODE_RX_UNDERSIZED_FRAMES causes undersized frames (frames
|
|
|
+//! shorter than 64 bytes but with no errors) to the application. If this
|
|
|
+//! option is not selected, all undersized frames are dropped by the receiver
|
|
|
+//! unless it has already started transferring them to the receive FIFO due to
|
|
|
+//! the receive threshold setting.
|
|
|
+//! - \b EMAC_MODE_OPERATE_2ND_FRAME enables the transmit DMA to operate on a
|
|
|
+//! second frame while waiting for the previous frame to be transmitted and
|
|
|
+//! associated status and timestamps to be reported. If absent, the transmit
|
|
|
+//! DMA works on a single frame at any one time, waiting for that frame to be
|
|
|
+//! transmitted and its status to be received before moving on to the next
|
|
|
+//! frame.
|
|
|
+//!
|
|
|
+//! The \e ui32RxMaxFrameSize parameter may be used to override the default
|
|
|
+//! setting for the maximum number of bytes that can be received in a frame
|
|
|
+//! before that frame is flagged as being in error. If the parameter is set
|
|
|
+//! to 0, the default hardware settings are applied. If non-zero, any frame
|
|
|
+//! received which is longer than the \e ui32RxMaxFrameSize, regardless of
|
|
|
+//! whether the MAC is configured for normal or Jumbo frame operation, is
|
|
|
+//! flagged as an error.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACConfigSet(uint32_t ui32Base, uint32_t ui32Config, uint32_t ui32ModeFlags,
|
|
|
+ uint32_t ui32RxMaxFrameSize)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check. Note that we allow TX_ENABLED and RX_ENABLED
|
|
|
+ // here because we'll mask them off before writing the value and this
|
|
|
+ // makes back-to-back EMACConfigGet/EMACConfigSet calls work without the
|
|
|
+ // caller needing to explicitly remove these bits from the parameter.
|
|
|
+ //
|
|
|
+ ASSERT((ui32Config & ~(VALID_CONFIG_FLAGS | EMAC_CONFIG_TX_ENABLED |
|
|
|
+ EMAC_CONFIG_RX_ENABLED)) == 0);
|
|
|
+ ASSERT(!ui32RxMaxFrameSize || ((ui32RxMaxFrameSize < 0x4000) &&
|
|
|
+ (ui32RxMaxFrameSize > 1522)));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the configuration flags as specified. Note that we unconditionally
|
|
|
+ // OR in the EMAC_CFG_PS bit here since this implementation supports only
|
|
|
+ // MII and RMII interfaces to the PHYs.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) =
|
|
|
+ ((HWREG(ui32Base + EMAC_O_CFG) & ~VALID_CONFIG_FLAGS) | ui32Config |
|
|
|
+ EMAC_CFG_PS);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the maximum receive frame size. If 0 is passed, this implies
|
|
|
+ // that the default maximum frame size should be used so just turn off
|
|
|
+ // the override.
|
|
|
+ //
|
|
|
+ if (ui32RxMaxFrameSize)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_WDOGTO) = ui32RxMaxFrameSize | EMAC_WDOGTO_PWE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_WDOGTO) &= ~EMAC_WDOGTO_PWE;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the operating mode register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) = ui32ModeFlags;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the Ethernet MAC's current basic configuration parameters.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param pui32Config points to storage that is written with Ethernet MAC
|
|
|
+//! configuration.
|
|
|
+//! \param pui32Mode points to storage that is written with Ethernet MAC mode
|
|
|
+//! information.
|
|
|
+//! \param pui32RxMaxFrameSize points to storage that is written with the
|
|
|
+//! maximum receive frame size.
|
|
|
+//!
|
|
|
+//! This function is called to query the basic operating parameters for the
|
|
|
+//! MAC and its DMA engines.
|
|
|
+//!
|
|
|
+//! The \e pui32Config parameter is written with the logical OR of various
|
|
|
+//! fields and flags. The first field describes which MAC address is used
|
|
|
+//! during insertion or replacement for all transmitted frames. Valid options
|
|
|
+//! are
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_USE_MACADDR1
|
|
|
+//! - \b EMAC_CONFIG_USE_MACADDR0
|
|
|
+//!
|
|
|
+//! The interframe gap between transmitted frames is given using one of the
|
|
|
+//! following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_96BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_88BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_80BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_72BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_64BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_56BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_48BITS
|
|
|
+//! - \b EMAC_CONFIG_IF_GAP_40BITS
|
|
|
+//!
|
|
|
+//! The number of bytes of preamble added to the beginning of every transmitted
|
|
|
+//! frame is described using one of the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_7BYTE_PREAMBLE
|
|
|
+//! - \b EMAC_CONFIG_5BYTE_PREAMBLE
|
|
|
+//! - \b EMAC_CONFIG_3BYTE_PREAMBLE
|
|
|
+//!
|
|
|
+//! The back-off limit determines the range of the random time that the MAC
|
|
|
+//! delays after a collision and before attempting to retransmit a frame. One
|
|
|
+//! of the following values provides the currently selected limit. In each
|
|
|
+//! case the retransmission delay in terms of 512 bit time slots, is the
|
|
|
+//! lower of (2 ** N) and a random number between 0 and the reported
|
|
|
+//! backoff-limit.
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_1024
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_256
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_16
|
|
|
+//! - \b EMAC_CONFIG_BO_LIMIT_2
|
|
|
+//!
|
|
|
+//! Handling of insertion or replacement of the source address in all
|
|
|
+//! transmitted frames is described by one of the following fields:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_SA_INSERT causes the MAC address (0 or 1 depending
|
|
|
+//! on whether \b EMAC_CONFIG_USE_MACADDR0 or \b EMAC_CONFIG_USE_MACADDR1
|
|
|
+//! was specified) to be inserted into all transmitted frames.
|
|
|
+//! - \b EMAC_CONFIG_SA_REPLACE causes the MAC address to be replaced with
|
|
|
+//! the selected address in all transmitted frames.
|
|
|
+//! - \b EMAC_CONFIG_SA_FROM_DESCRIPTOR causes control of source address
|
|
|
+//! insertion or deletion to be controlled by fields in the DMA transmit
|
|
|
+//! descriptor, allowing control on a frame-by-frame basis.
|
|
|
+//!
|
|
|
+//! Whether the interface attempts to operate in full- or half-duplex mode is
|
|
|
+//! reported by one of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_FULL_DUPLEX
|
|
|
+//! - \b EMAC_CONFIG_HALF_DUPLEX
|
|
|
+//!
|
|
|
+//! The following additional flags may also be included:
|
|
|
+//!
|
|
|
+//! - \b EMAC_CONFIG_2K_PACKETS indicates that IEEE802.3as support for 2K
|
|
|
+//! packets is enabled. When present, the MAC considers all frames up to 2000
|
|
|
+//! bytes in length as normal packets. When \b EMAC_CONFIG_JUMBO_ENABLE is
|
|
|
+//! not reported, all frames larger than 2000 bytes are treated as Giant
|
|
|
+//! frames. The value of this flag should be ignored if
|
|
|
+//! \b EMAC_CONFIG_JUMBO_ENABLE is also reported.
|
|
|
+//! - \b EMAC_CONFIG_STRIP_CRC indicates that the 4-byte CRC of all Ethernet
|
|
|
+//! type frames is being stripped and dropped before the frame is forwarded to
|
|
|
+//! the application.
|
|
|
+//! - \b EMAC_CONFIG_JABBER_DISABLE indicates that the the jabber timer on the
|
|
|
+//! transmitter is disabled, allowing frames of up to 16384 bytes to be
|
|
|
+//! transmitted. If this flag is absent, the MAC does not allow more than 2048
|
|
|
+//! (or 10240 if \b EMAC_CONFIG_JUMBO_ENABLE is reported) bytes to be sent in
|
|
|
+//! any one frame.
|
|
|
+//! - \b EMAC_CONFIG_JUMBO_ENABLE indicates that Jumbo Frames of up to 9018
|
|
|
+//! (or 9022 if using VLAN tagging) are enabled.
|
|
|
+//! - \b EMAC_CONFIG_CS_DISABLE indicates that Carrier Sense is disabled
|
|
|
+//! during transmission when operating in half-duplex mode.
|
|
|
+//! - \b EMAC_CONFIG_100MBPS indicates that the MAC is using 100Mbps
|
|
|
+//! signaling to communicate with the PHY.
|
|
|
+//! - \b EMAC_CONFIG_RX_OWN_DISABLE indicates that reception of transmitted
|
|
|
+//! frames is disabled when operating in half-duplex mode.
|
|
|
+//! - \b EMAC_CONFIG_LOOPBACK indicates that internal loopback is enabled.
|
|
|
+//! - \b EMAC_CONFIG_CHECKSUM_OFFLOAD indicates that IPv4 header checksum
|
|
|
+//! checking and IPv4 or IPv6 TCP, UPD or ICMP payload checksum checking is
|
|
|
+//! enabled. The results of the checksum calculations are reported via status
|
|
|
+//! fields in the DMA receive descriptors.
|
|
|
+//! - \b EMAC_CONFIG_RETRY_DISABLE indicates that retransmission is disabled
|
|
|
+//! in cases where half-duplex mode is in use and a collision occurs. This
|
|
|
+//! condition causes the current frame to be ignored and a frame abort to be
|
|
|
+//! reported in the transmit frame status.
|
|
|
+//! - \b EMAC_CONFIG_AUTO_CRC_STRIPPING indicates that the last 4 bytes
|
|
|
+//! (frame check sequence) from all Ether type frames are being stripped before
|
|
|
+//! frames are forwarded to the application.
|
|
|
+//! - \b EMAC_CONFIG_DEFERRAL_CHK_ENABLE indicates that transmit deferral
|
|
|
+//! checking is disabled in half-duplex mode. When enabled, the transmitter
|
|
|
+//! reports an error if it is unable to transmit a frame for more than 24288
|
|
|
+//! bit times (or 155680 bit times in Jumbo frame mode) due to an active
|
|
|
+//! carrier sense signal on the MII.
|
|
|
+//! - \b EMAC_CONFIG_TX_ENABLED indicates that the MAC transmitter is
|
|
|
+//! currently enabled.
|
|
|
+//! - \b EMAC_CONFIG_RX_ENABLED indicates that the MAC receiver is
|
|
|
+//! currently enabled.
|
|
|
+//!
|
|
|
+//! The \e pui32ModeFlags parameter is written with operating parameters
|
|
|
+//! related to the internal MAC FIFOs. It comprises a logical OR of the
|
|
|
+//! following fields. The first field reports the transmit FIFO threshold.
|
|
|
+//! Transmission of a frame begins when this amount of data or a full frame
|
|
|
+//! exists in the transmit FIFO. This field should be ignored if
|
|
|
+//! \b EMAC_MODE_TX_STORE_FORWARD is also reported. One of the following
|
|
|
+//! values is reported:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_16_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_24_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_32_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_40_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_64_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_128_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_192_BYTES
|
|
|
+//! - \b EMAC_MODE_TX_THRESHOLD_256_BYTES
|
|
|
+//!
|
|
|
+//! The second field reports the receive FIFO threshold. DMA transfers of
|
|
|
+//! received data begin either when the receive FIFO contains a full frame
|
|
|
+//! or this number of bytes. This field should be ignored if
|
|
|
+//! \b EMAC_MODE_RX_STORE_FORWARD is included. One of the following values
|
|
|
+//! is reported:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_64_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_32_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_96_BYTES
|
|
|
+//! - \b EMAC_MODE_RX_THRESHOLD_128_BYTES
|
|
|
+//!
|
|
|
+//! The following additional flags may be included:
|
|
|
+//!
|
|
|
+//! - \b EMAC_MODE_KEEP_BAD_CRC indicates that frames with TCP/IP checksum
|
|
|
+//! errors are being forwarded to the application if those frames do not have
|
|
|
+//! any errors (including FCS errors) in the Ethernet framing. In these cases,
|
|
|
+//! the frames have errors only in the payload. If this flag is not reported,
|
|
|
+//! all frames with any detected error are discarded unless
|
|
|
+//! \b EMAC_MODE_RX_ERROR_FRAMES is also reported.
|
|
|
+//! - \b EMAC_MODE_RX_STORE_FORWARD indicates that the receive DMA is
|
|
|
+//! configured to read frames from the FIFO only after the complete frame has
|
|
|
+//! been written to it. If this mode is enabled, the receive threshold is
|
|
|
+//! ignored.
|
|
|
+//! - \b EMAC_MODE_RX_FLUSH_DISABLE indicates that the flushing of received
|
|
|
+//! frames is disabled in cases where receive descriptors or buffers are
|
|
|
+//! unavailable.
|
|
|
+//! - \b EMAC_MODE_TX_STORE_FORWARD indicates that the transmitter is
|
|
|
+//! configured to transmit a frame only after the whole frame has been written
|
|
|
+//! to the transmit FIFO. If this mode is enabled, the transmit threshold is
|
|
|
+//! ignored.
|
|
|
+//! - \b EMAC_MODE_RX_ERROR_FRAMES indicates that all frames other than runt
|
|
|
+//! error frames are being forwarded to the receive DMA regardless of any
|
|
|
+//! errors detected in the frames.
|
|
|
+//! - \b EMAC_MODE_RX_UNDERSIZED_FRAMES indicates that undersized frames
|
|
|
+//! (frames shorter than 64 bytes but with no errors) are being forwarded to
|
|
|
+//! the application. If this option is not reported, all undersized frames are
|
|
|
+//! dropped by the receiver unless it has already started transferring them to
|
|
|
+//! the receive FIFO due to the receive threshold setting.
|
|
|
+//! - \b EMAC_MODE_OPERATE_2ND_FRAME indicates that the transmit DMA is
|
|
|
+//! configured to operate on a second frame while waiting for the previous
|
|
|
+//! frame to be transmitted and associated status and timestamps to be reported.
|
|
|
+//! If absent, the transmit DMA works on a single frame at any one time,
|
|
|
+//! waiting for that frame to be transmitted and its status to be received
|
|
|
+//! before moving on to the next frame.
|
|
|
+//! - \b EMAC_MODE_TX_DMA_ENABLED indicates that the transmit DMA engine is
|
|
|
+//! currently enabled.
|
|
|
+//! - \b EMAC_MODE_RX_DMA_ENABLED indicates that the receive DMA engine is
|
|
|
+//! currently enabled.
|
|
|
+//!
|
|
|
+//! The \e pui32RxMaxFrameSize is written with the currently configured maximum
|
|
|
+//! receive packet size. Packets larger than this are flagged as being in
|
|
|
+//! error.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACConfigGet(uint32_t ui32Base, uint32_t *pui32Config, uint32_t *pui32Mode,
|
|
|
+ uint32_t *pui32RxMaxFrameSize)
|
|
|
+{
|
|
|
+ uint32_t ui32Value;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(pui32Mode);
|
|
|
+ ASSERT(pui32Config);
|
|
|
+ ASSERT(pui32RxMaxFrameSize);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the mode information from the operation mode register.
|
|
|
+ //
|
|
|
+ *pui32Mode = HWREG(ui32Base + EMAC_O_DMAOPMODE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the current configuration flags from the EMAC_O_CFG register.
|
|
|
+ //
|
|
|
+ *pui32Config = (HWREG(ui32Base + EMAC_O_CFG) &
|
|
|
+ (VALID_CONFIG_FLAGS | EMAC_CONFIG_TX_ENABLED |
|
|
|
+ EMAC_CONFIG_RX_ENABLED));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the receive packet size watchdog value.
|
|
|
+ //
|
|
|
+ ui32Value = HWREG(ui32Base + EMAC_O_WDOGTO);
|
|
|
+ if (ui32Value & EMAC_WDOGTO_PWE)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // The watchdog is enables so the maximum packet length can be read
|
|
|
+ // from the watchdog timeout register.
|
|
|
+ //
|
|
|
+ *pui32RxMaxFrameSize = ui32Value & EMAC_WDOGTO_WTO_M;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // The maximum packet size override found in the watchdog timer
|
|
|
+ // register is not enabled so the maximum packet size is determined
|
|
|
+ // by whether or not jumbo frame mode is enabled.
|
|
|
+ //
|
|
|
+ if (HWREG(ui32Base + EMAC_O_CFG) & EMAC_CFG_JFEN)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Jumbo frames are enabled so the watchdog kicks in at 10240
|
|
|
+ // bytes.
|
|
|
+ //
|
|
|
+ *pui32RxMaxFrameSize = 10240;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Jumbo frames are not enabled so the watchdog kicks in at
|
|
|
+ // 2048 bytes.
|
|
|
+ //
|
|
|
+ *pui32RxMaxFrameSize = 2048;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the MAC address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param ui32Index is the zero-based index of the MAC address to set.
|
|
|
+//! \param pui8MACAddr is the pointer to the array of MAC-48 address octets.
|
|
|
+//!
|
|
|
+//! This function programs the IEEE-defined MAC-48 address specified in
|
|
|
+//! \e pui8MACAddr 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). Index 0 is used to hold
|
|
|
+//! the local node's MAC address which is inserted into all transmitted
|
|
|
+//! packets.
|
|
|
+//!
|
|
|
+//! The controller may support several Ethernet MAC address slots, each of which
|
|
|
+//! may be programmed independently and used to filter incoming packets. The
|
|
|
+//! number of MAC addresses that the hardware supports may be queried using a
|
|
|
+//! call to EMACNumAddrGet(). The value of the \e ui32Index parameter must
|
|
|
+//! lie in the range from 0 to (number of MAC addresses - 1) inclusive.
|
|
|
+//!
|
|
|
+//! The MAC-48 address is defined as 6 octets, illustrated by the following
|
|
|
+//! example address. The numbers are shown 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 (00-00-80) 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''.
|
|
|
+//!
|
|
|
+//! The address passed to this function in the \e pui8MACAddr array is
|
|
|
+//! ordered with the first byte to be transmitted in the first array entry.
|
|
|
+//! For example, the address given above could be represented using the
|
|
|
+//! following array:
|
|
|
+//!
|
|
|
+//! uint8_t g_pui8MACAddr[] = { 0xAC, 0xDE, 0x48, 0x00, 0x00, 0x80 };
|
|
|
+//!
|
|
|
+//! If the MAC address set by this function is currently enabled, it remains
|
|
|
+//! enabled following this call. Similarly, any filter configured for
|
|
|
+//! the MAC address remains unaffected by a change in the address.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACAddrSet(uint32_t ui32Base, uint32_t ui32Index, const uint8_t *pui8MACAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Index < NUM_MAC_ADDR);
|
|
|
+ ASSERT(pui8MACAddr);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the high 2 bytes of the MAC address. Note that we must set the
|
|
|
+ // registers in this order since the address is latched internally
|
|
|
+ // on the write to EMAC_O_ADDRL.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_ADDRH(ui32Index)) =
|
|
|
+ ((HWREG(ui32Base + EMAC_O_ADDRH(ui32Index)) & 0xFFFF0000) |
|
|
|
+ pui8MACAddr[4] | (pui8MACAddr[5] << 8));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the first 4 bytes of the MAC address
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_ADDRL(ui32Index)) =
|
|
|
+ (pui8MACAddr[0] | (pui8MACAddr[1] << 8) | (pui8MACAddr[2] << 16) |
|
|
|
+ (pui8MACAddr[3] << 24));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Gets one of the MAC addresses stored in the Ethernet controller.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Index is the zero-based index of the MAC address to return.
|
|
|
+//! \param pui8MACAddr is the pointer to the location in which to store the
|
|
|
+//! array of MAC-48 address octets.
|
|
|
+//!
|
|
|
+//! This function reads the currently programmed MAC address into the
|
|
|
+//! \e pui8MACAddr buffer. The \e ui32Index parameter defines which of the
|
|
|
+//! hardware's MAC addresses to return. The number of MAC addresses supported
|
|
|
+//! by the controller may be queried using a call to EMACNumAddrGet().
|
|
|
+//! Index 0 refers to the MAC address of the local node. Other indices are
|
|
|
+//! used to define MAC addresses when filtering incoming packets.
|
|
|
+//!
|
|
|
+//! The address is written to the pui8MACAddr array ordered with the first byte
|
|
|
+//! to be transmitted in the first array entry. For example, if the address
|
|
|
+//! is written in its usual form with the Organizationally Unique Identifier
|
|
|
+//! (OUI) shown first as:
|
|
|
+//!
|
|
|
+//! AC-DE-48-00-00-80
|
|
|
+//!
|
|
|
+//! the data is returned with 0xAC in the first byte of the array, 0xDE in
|
|
|
+//! the second, 0x48 in the third and so on.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACAddrGet(uint32_t ui32Base, uint32_t ui32Index, uint8_t *pui8MACAddr)
|
|
|
+{
|
|
|
+ uint32_t ui32Val;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Index < NUM_MAC_ADDR);
|
|
|
+ ASSERT(pui8MACAddr);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the first 4 bytes of the MAC address.
|
|
|
+ //
|
|
|
+ ui32Val = HWREG(ui32Base + EMAC_O_ADDRL(ui32Index));
|
|
|
+ pui8MACAddr[0] = ui32Val & 0xFF;
|
|
|
+ pui8MACAddr[1] = (ui32Val >> 8) & 0xFF;
|
|
|
+ pui8MACAddr[2] = (ui32Val >> 16) & 0xFF;
|
|
|
+ pui8MACAddr[3] = (ui32Val >> 24) & 0xFF;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the last 2 bytes of the MAC address.
|
|
|
+ //
|
|
|
+ ui32Val = HWREG(ui32Base + EMAC_O_ADDRH(ui32Index));
|
|
|
+ pui8MACAddr[4] = ui32Val & 0xFF;
|
|
|
+ pui8MACAddr[5] = (ui32Val >> 8) & 0xFF;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the number of MAC addresses supported by the Ethernet controller.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! This function may be used to determine the number of MAC addresses that the
|
|
|
+//! given controller supports. MAC address slots may be used when performing
|
|
|
+//! perfect (rather than hash table) filtering of packets.
|
|
|
+//!
|
|
|
+//! \return Returns the number of supported MAC addresses.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACNumAddrGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // The only Ethernet controller on MSP432E4 supports 4 MAC addresses.
|
|
|
+ //
|
|
|
+ return (NUM_MAC_ADDR);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets filtering parameters associated with one of the configured MAC
|
|
|
+//! addresses.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Index is the index of the MAC address slot for which the filter
|
|
|
+//! is to be set.
|
|
|
+//! \param ui32Config sets the filter parameters for the given MAC address.
|
|
|
+//!
|
|
|
+//! This function sets filtering parameters associated with one of the MAC
|
|
|
+//! address slots that the controller supports. This configuration is used
|
|
|
+//! when perfect filtering (rather than hash table filtering) is selected.
|
|
|
+//!
|
|
|
+//! Valid values for \e ui32Index are from 1 to (number of MAC address
|
|
|
+//! slots - 1). The number of supported MAC address slots may be found by
|
|
|
+//! calling EMACNumAddrGet(). MAC index 0 is the local MAC address and does
|
|
|
+//! not have filtering parameters associated with it.
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter determines how the given MAC address is used
|
|
|
+//! when filtering incoming Ethernet frames. It is comprised of a logical OR
|
|
|
+//! of the fields:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FILTER_ADDR_ENABLE indicates that this MAC address is enabled
|
|
|
+//! and should be used when performing perfect filtering. If this flag is
|
|
|
+//! absent, the MAC address at the given index is disabled and is not used
|
|
|
+//! in filtering.
|
|
|
+//! - \b EMAC_FILTER_SOURCE_ADDR indicates that the MAC address at the given
|
|
|
+//! index is compared to the source address of incoming frames while
|
|
|
+//! performing perfect filtering. If absent, the MAC address is compared
|
|
|
+//! against the destination address.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_6 indicates that the MAC should ignore the
|
|
|
+//! sixth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_5 indicates that the MAC should ignore the
|
|
|
+//! fifth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_4 indicates that the MAC should ignore the
|
|
|
+//! fourth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_3 indicates that the MAC should ignore the
|
|
|
+//! third byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_2 indicates that the MAC should ignore the
|
|
|
+//! second byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_1 indicates that the MAC should ignore the
|
|
|
+//! first byte of the source or destination address when filtering.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACAddrFilterSet(uint32_t ui32Base, uint32_t ui32Index, uint32_t ui32Config)
|
|
|
+{
|
|
|
+ uint32_t ui32Val;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Index < NUM_MAC_ADDR);
|
|
|
+ ASSERT((ui32Config & ~(EMAC_FILTER_BYTE_MASK_M |
|
|
|
+ EMAC_FILTER_ADDR_ENABLE |
|
|
|
+ EMAC_FILTER_SOURCE_ADDR)) == 0);
|
|
|
+ ASSERT(ui32Index);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the filter configuration for a particular MAC address.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_ADDRH(ui32Index)) =
|
|
|
+ (HWREG(ui32Base + EMAC_O_ADDRH(ui32Index)) & 0xFFFF) | ui32Config;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read and rewrite the low half of the MAC address register to ensure
|
|
|
+ // that the upper half's data is latched.
|
|
|
+ //
|
|
|
+ ui32Val = HWREG(ui32Base + EMAC_O_ADDRL(ui32Index));
|
|
|
+ HWREG(ui32Base + EMAC_O_ADDRL(ui32Index)) = ui32Val;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Gets filtering parameters associated with one of the configured MAC
|
|
|
+//! addresses.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Index is the index of the MAC address slot for which the filter
|
|
|
+//! is to be queried.
|
|
|
+//!
|
|
|
+//! This function returns filtering parameters associated with one of the MAC
|
|
|
+//! address slots that the controller supports. This configuration is used
|
|
|
+//! when perfect filtering (rather than hash table filtering) is selected.
|
|
|
+//!
|
|
|
+//! Valid values for \e ui32Index are from 1 to (number of MAC address
|
|
|
+//! slots - 1). The number of supported MAC address slots may be found by
|
|
|
+//! calling EMACNumAddrGet(). MAC index 0 is the local MAC address and does
|
|
|
+//! not have filtering parameters associated with it.
|
|
|
+//!
|
|
|
+//! \return Returns the filter configuration as the logical OR of the
|
|
|
+//! following labels:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FILTER_ADDR_ENABLE indicates that this MAC address is enabled
|
|
|
+//! and is used when performing perfect filtering. If this flag is absent,
|
|
|
+//! the MAC address at the given index is disabled and is not used in
|
|
|
+//! filtering.
|
|
|
+//! - \b EMAC_FILTER_SOURCE_ADDR indicates that the MAC address at the given
|
|
|
+//! index is compared to the source address of incoming frames while performing
|
|
|
+//! perfect filtering. If absent, the MAC address is compared against the
|
|
|
+//! destination address.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_6 indicates that the MAC ignores the
|
|
|
+//! sixth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_5 indicates that the MAC ignores the
|
|
|
+//! fifth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_4 indicates that the MAC ignores the
|
|
|
+//! fourth byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_3 indicates that the MAC ignores the
|
|
|
+//! third byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_2 indicates that the MAC ignores the
|
|
|
+//! second byte of the source or destination address when filtering.
|
|
|
+//! - \b EMAC_FILTER_MASK_BYTE_1 indicates that the MAC ignores the
|
|
|
+//! first byte of the source or destination address when filtering.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACAddrFilterGet(uint32_t ui32Base, uint32_t ui32Index)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Index < NUM_MAC_ADDR);
|
|
|
+ ASSERT(ui32Index);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read and return the filter settings for the requested MAC address slot.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_ADDRH(ui32Index)) &
|
|
|
+ (EMAC_FILTER_BYTE_MASK_M | EMAC_FILTER_ADDR_ENABLE |
|
|
|
+ EMAC_FILTER_SOURCE_ADDR));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets options related to Ethernet frame filtering.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32FilterOpts is a logical OR of flags defining the required MAC
|
|
|
+//! address filtering options.
|
|
|
+//!
|
|
|
+//! This function allows various filtering options to be defined and allows
|
|
|
+//! an application to control which frames are received based on various
|
|
|
+//! criteria related to the frame source and destination MAC addresses or VLAN
|
|
|
+//! tagging.
|
|
|
+//!
|
|
|
+//! The \e ui32FilterOpts parameter is a logical OR of any of the following
|
|
|
+//! flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FRMFILTER_RX_ALL configures the MAC to pass all received frames
|
|
|
+//! regardless of whether or not they pass any address filter that is
|
|
|
+//! configured. The receive status word in the relevant DMA descriptor is
|
|
|
+//! updated to indicate whether the configured filter passed or failed for
|
|
|
+//! the frame.
|
|
|
+//! - \b EMAC_FRMFILTER_VLAN configures the MAC to drop any frames that do
|
|
|
+//! not pass the VLAN tag comparison.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_AND_PERFECT configures the MAC to filter frames
|
|
|
+//! based on both any perfect filters set and the hash filter if enabled using
|
|
|
+//! \b EMAC_FRMFILTER_HASH_UNICAST or \b EMAC_FRMFILTER_HASH_MULTICAST. In
|
|
|
+//! this case, only if both filters fail is the packet rejected. If this
|
|
|
+//! option is absent, only one of the filter types is used, as controlled by
|
|
|
+//! \b EMAC_FRMFILTER_HASH_UNICAST and \b EMAC_FRMFILTER_HASH_MULTICAST
|
|
|
+//! for unicast and multicast frames respectively.
|
|
|
+//! - \b EMAC_FRMFILTER_SADDR configures the MAC to drop received frames
|
|
|
+//! when the source address field in the frame does not match the values
|
|
|
+//! programmed into the enabled SA registers.
|
|
|
+//! - \b EMAC_FRMFILTER_INV_SADDR enables inverse source address filtering.
|
|
|
+//! When this option is specified, frames for which the SA does not match the
|
|
|
+//! SA registers are marked as passing the source address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_BROADCAST configures the MAC to discard all incoming
|
|
|
+//! broadcast frames.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_MULTICAST configures the MAC to pass all
|
|
|
+//! incoming frames with multicast destinations addresses.
|
|
|
+//! - \b EMAC_FRMFILTER_INV_DADDR inverts the sense of the destination
|
|
|
+//! address filtering for both unicast and multicast frames.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_MULTICAST enables destination address filtering
|
|
|
+//! of received multicast frames using the hash table. If absent, perfect
|
|
|
+//! destination address filtering is used. If used in conjunction with \b
|
|
|
+//! EMAC_FRMFILTER_HASH_AND_PERFECT, this flag indicates that the hash filter
|
|
|
+//! should be used for incoming multicast packets along with the perfect
|
|
|
+//! filter.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_UNICAST enables destination address filtering
|
|
|
+//! of received unicast frames using the hash table. If absent, perfect
|
|
|
+//! destination address filtering is used. If used in conjunction with \b
|
|
|
+//! EMAC_FRMFILTER_HASH_AND_PERFECT, this flag indicates that the hash filter
|
|
|
+//! should be used for incoming unicast packets along with the perfect filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PROMISCUOUS configures the MAC to operate in
|
|
|
+//! promiscuous mode where all received frames are passed to the application
|
|
|
+//! and the SA and DA filter status bits of the descriptor receive status word
|
|
|
+//! are always cleared.
|
|
|
+//!
|
|
|
+//! Control frame filtering may be configured by ORing one of the following
|
|
|
+//! values into \e ui32FilterOpts:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_NO_CTRL prevents any control frame from reaching
|
|
|
+//! the application.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_NO_PAUSE passes all control frames other than
|
|
|
+//! PAUSE even if they fail the configured address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_ALL_CTRL passes all control frames, including
|
|
|
+//! PAUSE even if they fail the configured address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_ADDR_CTRL passes all control frames only if they
|
|
|
+//! pass the configured address filter.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACFrameFilterSet(uint32_t ui32Base, uint32_t ui32FilterOpts)
|
|
|
+{
|
|
|
+ ASSERT((ui32FilterOpts & ~VALID_FRMFILTER_FLAGS) == 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the Ethernet MAC frame filter according to the flags passed.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_FRAMEFLTR) =
|
|
|
+ ((HWREG(ui32Base + EMAC_O_FRAMEFLTR) & ~VALID_FRMFILTER_FLAGS) |
|
|
|
+ ui32FilterOpts);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current Ethernet frame filtering settings.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be called to retrieve the frame filtering configuration
|
|
|
+//! set using a prior call to EMACFrameFilterSet().
|
|
|
+//!
|
|
|
+//! \return Returns a value comprising the logical OR of various flags
|
|
|
+//! indicating the frame filtering options in use. Possible flags are:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FRMFILTER_RX_ALL indicates that the MAC to is configured to
|
|
|
+//! pass all received frames regardless of whether or not they pass any
|
|
|
+//! address filter that is configured. The receive status word in the
|
|
|
+//! relevant DMA descriptor is updated to indicate whether the configured
|
|
|
+//! filter passed or failed for the frame.
|
|
|
+//! - \b EMAC_FRMFILTER_VLAN indicates that the MAC is configured to drop any
|
|
|
+//! frames which do not pass the VLAN tag comparison.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_AND_PERFECT indicates that the MAC is configured
|
|
|
+//! to pass frames if they match either the hash filter or the perfect filter.
|
|
|
+//! If this flag is absent, frames passing based on the result of a single
|
|
|
+//! filter, the perfect filter if \b EMAC_FRMFILTER_HASH_MULTICAST or
|
|
|
+//! \b EMAC_FRMFILTER_HASH_UNICAST are clear or the hash filter otherwise.
|
|
|
+//! - \b EMAC_FRMFILTER_SADDR indicates that the MAC is configured to drop
|
|
|
+//! received frames when the source address field in the frame does not match
|
|
|
+//! the values programmed into the enabled SA registers.
|
|
|
+//! - \b EMAC_FRMFILTER_INV_SADDR enables inverse source address filtering.
|
|
|
+//! When this option is specified, frames for which the SA does not match the
|
|
|
+//! SA registers are marked as passing the source address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_BROADCAST indicates that the MAC is configured to
|
|
|
+//! discard all incoming broadcast frames.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_MULTICAST indicates that the MAC is configured
|
|
|
+//! to pass all incoming frames with multicast destinations addresses.
|
|
|
+//! - \b EMAC_FRMFILTER_INV_DADDR indicates that the sense of the destination
|
|
|
+//! address filtering for both unicast and multicast frames is inverted.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_MULTICAST indicates that destination address
|
|
|
+//! filtering of received multicast frames is enabled using the hash table. If
|
|
|
+//! absent, perfect destination address filtering is used. If used in
|
|
|
+//! conjunction with \b EMAC_FRMFILTER_HASH_AND_PERFECT, this flag indicates
|
|
|
+//! that the hash filter should be used for incoming multicast packets along
|
|
|
+//! with the perfect filter.
|
|
|
+//! - \b EMAC_FRMFILTER_HASH_UNICAST indicates that destination address
|
|
|
+//! filtering of received unicast frames is enabled using the hash table. If
|
|
|
+//! absent, perfect destination address filtering is used. If used in
|
|
|
+//! conjunction with \b EMAC_FRMFILTER_HASH_AND_PERFECT, this flag indicates
|
|
|
+//! that the hash filter should be used for incoming unicast packets along with
|
|
|
+//! the perfect filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PROMISCUOUS indicates that the MAC is configured to
|
|
|
+//! operate in promiscuous mode where all received frames are passed to the
|
|
|
+//! application and the SA and DA filter status bits of the descriptor receive
|
|
|
+//! status word are always cleared.
|
|
|
+//!
|
|
|
+//! Control frame filtering configuration is indicated by one of the following
|
|
|
+//! values which may be extracted from the returned value using the mask
|
|
|
+//! \b EMAC_FRMFILTER_PASS_MASK:
|
|
|
+//!
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_NO_CTRL prevents any control frame from reaching
|
|
|
+//! the application.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_NO_PAUSE passes all control frames other than
|
|
|
+//! PAUSE even if they fail the configured address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_ALL_CTRL passes all control frames, including
|
|
|
+//! PAUSE even if they fail the configured address filter.
|
|
|
+//! - \b EMAC_FRMFILTER_PASS_ADDR_CTRL passes all control frames only if they
|
|
|
+//! pass the configured address filter.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACFrameFilterGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the current MAC frame filter setting.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_FRAMEFLTR) & VALID_FRMFILTER_FLAGS);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the MAC address hash filter table.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32HashHi is the upper 32 bits of the current 64-bit hash filter
|
|
|
+//! table to set.
|
|
|
+//! \param ui32HashLo is the lower 32 bits of the current 64-bit hash filter
|
|
|
+//! table to set.
|
|
|
+//!
|
|
|
+//! This function may be used to set the current 64-bit hash filter table
|
|
|
+//! used by the MAC to filter incoming packets when hash filtering is enabled.
|
|
|
+//! Hash filtering is enabled by passing \b EMAC_FRMFILTER_HASH_UNICAST
|
|
|
+//! and/or \b EMAC_FRMFILTER_HASH_MULTICAST in the \e ui32FilterOpts parameter
|
|
|
+//! to EMACFrameFilterSet(). The current hash filter may be retrieved
|
|
|
+//! by calling EMACHashFilterGet().
|
|
|
+//!
|
|
|
+//! Hash table filtering allows many different MAC addresses to be filtered
|
|
|
+//! simultaneously at the cost of some false-positive results (in the form of
|
|
|
+//! packets passing the filter when their MAC address was not one of those
|
|
|
+//! required). A CRC of the packet source or destination MAC address is
|
|
|
+//! calculated and the bottom 6 bits are used as a bit index into the 64-bit
|
|
|
+//! hash filter table. If the bit in the hash table is set, the filter is
|
|
|
+//! considered to have passed. If the bit is clear, the filter fails and the
|
|
|
+//! packet is rejected (assuming normal rather than inverse filtering is
|
|
|
+//! configured).
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACHashFilterSet(uint32_t ui32Base, uint32_t ui32HashHi, uint32_t ui32HashLo)
|
|
|
+{
|
|
|
+ // Set the hash table with the values provided.
|
|
|
+ HWREG(ui32Base + EMAC_O_HASHTBLL) = ui32HashLo;
|
|
|
+ HWREG(ui32Base + EMAC_O_HASHTBLH) = ui32HashHi;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current MAC address hash filter table.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pui32HashHi points to storage to be written with the upper 32 bits
|
|
|
+//! of the current 64-bit hash filter table.
|
|
|
+//! \param pui32HashLo points to storage to be written with the lower 32 bits
|
|
|
+//! of the current 64-bit hash filter table.
|
|
|
+//!
|
|
|
+//! This function may be used to retrieve the current 64-bit hash filter table
|
|
|
+//! from the MAC prior to making changes and setting the new hash filter via a
|
|
|
+//! call to EMACHashFilterSet().
|
|
|
+//!
|
|
|
+//! Hash table filtering allows many different MAC addresses to be filtered
|
|
|
+//! simultaneously at the cost of some false-positive results in the form of
|
|
|
+//! packets passing the filter when their MAC address was not one of those
|
|
|
+//! required. A CRC of the packet source or destination MAC address is
|
|
|
+//! calculated and the bottom 6 bits are used as a bit index into the 64-bit
|
|
|
+//! hash filter table. If the bit in the hash table is set, the filter is
|
|
|
+//! considered to have passed. If the bit is clear, the filter fails and the
|
|
|
+//! packet is rejected (assuming normal rather than inverse filtering is
|
|
|
+//! configured).
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACHashFilterGet(uint32_t ui32Base, uint32_t *pui32HashHi,
|
|
|
+ uint32_t *pui32HashLo)
|
|
|
+{
|
|
|
+ ASSERT(pui32HashHi);
|
|
|
+ ASSERT(pui32HashLo);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the current hash table values.
|
|
|
+ //
|
|
|
+ *pui32HashLo = HWREG(ui32Base + EMAC_O_HASHTBLL);
|
|
|
+ *pui32HashHi = HWREG(ui32Base + EMAC_O_HASHTBLH);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the bit number to set in the MAC hash filter corresponding to a
|
|
|
+//! given MAC address.
|
|
|
+//!
|
|
|
+//! \param pui8MACAddr points to a buffer containing the 6-byte MAC address
|
|
|
+//! for which the hash filter bit is to be determined.
|
|
|
+//!
|
|
|
+//! This function may be used to determine which bit in the MAC address hash
|
|
|
+//! filter to set to describe a given 6-byte MAC address. The returned value is
|
|
|
+//! a 6-bit number where bit 5 indicates which of the two hash table words is
|
|
|
+//! affected and the bottom 5 bits indicate the bit number to set within that
|
|
|
+//! word. For example, if 0x22 (100010b) is returned, this indicates that bit
|
|
|
+//! 2 of word 1 (\e ui32HashHi as passed to EMACHashFilterSet()) must be set
|
|
|
+//! to describe the passed MAC address.
|
|
|
+//!
|
|
|
+//! \return Returns the bit number to set in the MAC hash table to describe the
|
|
|
+//! passed MAC address.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACHashFilterBitCalculate(uint8_t *pui8MACAddr)
|
|
|
+{
|
|
|
+ uint32_t ui32CRC, ui32Mask, ui32Loop;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(pui8MACAddr);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Calculate the CRC for the MAC address.
|
|
|
+ //
|
|
|
+ ui32CRC = Crc32(0xFFFFFFFF, pui8MACAddr, 6);
|
|
|
+ ui32CRC ^= 0xFFFFFFFF;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Determine the hash bit to use from the calculated CRC. This is the
|
|
|
+ // top 6 bits of the reversed CRC (or the bottom 6 bits of the calculated
|
|
|
+ // CRC with the bit order of those 6 bits reversed).
|
|
|
+ //
|
|
|
+ ui32Mask = 0;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Reverse the order of the bottom 6 bits of the calculated CRC.
|
|
|
+ //
|
|
|
+ for (ui32Loop = 0; ui32Loop < 6; ui32Loop++)
|
|
|
+ {
|
|
|
+ ui32Mask <<= 1;
|
|
|
+ ui32Mask |= (ui32CRC & 1);
|
|
|
+ ui32CRC >>= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the final hash table bit index.
|
|
|
+ //
|
|
|
+ return (ui32Mask);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the receive interrupt watchdog timer period.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//! \param ui8Timeout is the desired timeout expressed as a number of 256
|
|
|
+//! system clock periods.
|
|
|
+//!
|
|
|
+//! This function configures the receive interrupt watchdog timer.
|
|
|
+//! The \e uiTimeout parameter specifies the number of 256 system clock periods
|
|
|
+//! that elapse before the timer expires. In cases where the DMA has
|
|
|
+//! transferred a frame using a descriptor that has
|
|
|
+//! \b DES1_RX_CTRL_DISABLE_INT set, the watchdog causes a receive
|
|
|
+//! interrupt to be generated when it times out. The watchdog timer is reset
|
|
|
+//! whenever a packet is transferred to memory using a DMA descriptor that
|
|
|
+//! does not disable the receive interrupt.
|
|
|
+//!
|
|
|
+//! To disable the receive interrupt watchdog function, set \e ui8Timeout to 0.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRxWatchdogTimerSet(uint32_t ui32Base, uint8_t ui8Timeout)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Set the receive interrupt watchdog timeout period.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_RXINTWDT) = (uint32_t)ui8Timeout;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current Ethernet MAC status.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! This function returns information on the current status of all the main
|
|
|
+//! modules in the MAC transmit and receive data paths.
|
|
|
+//!
|
|
|
+//! \return Returns the current MAC status as a logical OR of any of the
|
|
|
+//! following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_STATUS_TX_NOT_EMPTY
|
|
|
+//! - \b EMAC_STATUS_TX_WRITING_FIFO
|
|
|
+//! - \b EMAC_STATUS_TX_PAUSED
|
|
|
+//! - \b EMAC_STATUS_MAC_NOT_IDLE
|
|
|
+//! - \b EMAC_STATUS_RWC_ACTIVE
|
|
|
+//! - \b EMAC_STATUS_RPE_ACTIVE
|
|
|
+//!
|
|
|
+//! The transmit frame controller status can be extracted from the returned
|
|
|
+//! value by ANDing with \b EMAC_STATUS_TFC_STATE_MASK and is one of the
|
|
|
+//! following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_STATUS_TFC_STATE_IDLE
|
|
|
+//! - \b EMAC_STATUS_TFC_STATE_WAITING
|
|
|
+//! - \b EMAC_STATUS_TFC_STATE_PAUSING
|
|
|
+//! - \b EMAC_STATUS_TFC_STATE_WRITING
|
|
|
+//!
|
|
|
+//! The transmit FIFO read controller status can be extracted from the returned
|
|
|
+//! value by ANDing with \b EMAC_STATUS_TRC_STATE_MASK and is one of the
|
|
|
+//! following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_STATUS_TRC_STATE_IDLE
|
|
|
+//! - \b EMAC_STATUS_TRC_STATE_READING
|
|
|
+//! - \b EMAC_STATUS_TRC_STATE_WAITING
|
|
|
+//! - \b EMAC_STATUS_TRC_STATE_STATUS
|
|
|
+//!
|
|
|
+//! The current receive FIFO levels can be extracted from the returned value
|
|
|
+//! by ANDing with \b EMAC_STATUS_RX_FIFO_LEVEL_MASK and is one of the
|
|
|
+//! following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_EMPTY indicating that the FIFO is empty.
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_BELOW indicating that the FIFO fill level is
|
|
|
+//! below the flow-control deactivate threshold.
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_ABOVE indicating that the FIFO fill level is
|
|
|
+//! above the flow-control activate threshold.
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_FULL indicating that the FIFO is full.
|
|
|
+//!
|
|
|
+//! The current receive FIFO state can be extracted from the returned value
|
|
|
+//! by ANDing with \b EMAC_STATUS_RX_FIFO_STATE_MASK and is one of the
|
|
|
+//! following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_IDLE
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_READING
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_STATUS
|
|
|
+//! - \b EMAC_STATUS_RX_FIFO_FLUSHING
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACStatusGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Read and return the MAC status register content.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_STATUS));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Orders the MAC DMA controller to attempt to acquire the next transmit
|
|
|
+//! descriptor.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! This function must be called to restart the transmitter if it has been
|
|
|
+//! suspended due to the current transmit DMA descriptor being owned by the
|
|
|
+//! host. Once the application writes new values to the descriptor and marks
|
|
|
+//! it as being owned by the MAC DMA, this function causes the hardware to
|
|
|
+//! attempt to acquire the descriptor and start transmission of the new
|
|
|
+//! data.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTxDMAPollDemand(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Any write to the MACTXPOLLD register causes the transmit DMA to attempt
|
|
|
+ // to resume.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TXPOLLD) = 0;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Orders the MAC DMA controller to attempt to acquire the next receive
|
|
|
+//! descriptor.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet controller.
|
|
|
+//!
|
|
|
+//! This function must be called to restart the receiver if it has been
|
|
|
+//! suspended due to the current receive DMA descriptor being owned by the
|
|
|
+//! host. Once the application reads any data from the descriptor and marks
|
|
|
+//! it as being owned by the MAC DMA, this function causes the hardware to
|
|
|
+//! attempt to acquire the descriptor before writing the next received packet
|
|
|
+//! into its buffer(s).
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRxDMAPollDemand(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Any write to the MACRXPOLLD register causes the receive DMA to attempt
|
|
|
+ // to resume.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_RXPOLLD) = 0;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the DMA receive descriptor list pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pDescriptor points to the first DMA descriptor in the list to
|
|
|
+//! be passed to the receive DMA engine.
|
|
|
+//!
|
|
|
+//! This function sets the Ethernet MAC's receive DMA descriptor list pointer.
|
|
|
+//! The \e pDescriptor pointer must point to one or more descriptor
|
|
|
+//! structures.
|
|
|
+//!
|
|
|
+//! When multiple descriptors are provided, they can be either chained or
|
|
|
+//! unchained. Chained descriptors are indicated by setting the
|
|
|
+//! \b DES0_TX_CTRL_CHAINED or \b DES1_RX_CTRL_CHAINED bit in the relevant
|
|
|
+//! word of the transmit or receive descriptor. If this bit is clear,
|
|
|
+//! unchained descriptors are assumed.
|
|
|
+//!
|
|
|
+//! Chained descriptors use a link pointer in each descriptor to
|
|
|
+//! point to the next descriptor in the chain.
|
|
|
+//!
|
|
|
+//! Unchained descriptors are assumed to be contiguous in memory with a
|
|
|
+//! consistent offset between the start of one descriptor and the next.
|
|
|
+//! If unchained descriptors are used, the \e pvLink field in the descriptor
|
|
|
+//! becomes available to store a second buffer pointer, allowing each
|
|
|
+//! descriptor to point to two buffers rather than one. In this case,
|
|
|
+//! the \e ui32DescSkipSize parameter to EMACInit() must previously have
|
|
|
+//! been set to the number of words between the end of one descriptor and
|
|
|
+//! the start of the next. This value must be 0 in cases where a packed array
|
|
|
+//! of \b tEMACDMADescriptor structures is used. If the application wishes to
|
|
|
+//! add new state fields to the end of the descriptor structure, the skip size
|
|
|
+//! should be set to accommodate the newly sized structure.
|
|
|
+//!
|
|
|
+//! Applications are responsible for initializing all descriptor fields
|
|
|
+//! appropriately before passing the descriptor list to the hardware.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRxDMADescriptorListSet(uint32_t ui32Base, tEMACDMADescriptor *pDescriptor)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(pDescriptor);
|
|
|
+ ASSERT(((uint32_t)pDescriptor & 3) == 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the supplied address to the MACRXDLADDR register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_RXDLADDR) = (uint32_t)pDescriptor;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns a pointer to the start of the DMA receive descriptor list.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function returns a pointer to the head of the Ethernet MAC's receive
|
|
|
+//! DMA descriptor list. This value corresponds to the pointer originally set
|
|
|
+//! using a call to EMACRxDMADescriptorListSet().
|
|
|
+//!
|
|
|
+//! \return Returns a pointer to the start of the DMA receive descriptor list.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+tEMACDMADescriptor *
|
|
|
+EMACRxDMADescriptorListGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the current receive DMA descriptor list pointer.
|
|
|
+ //
|
|
|
+ return ((tEMACDMADescriptor *)HWREG(ui32Base + EMAC_O_RXDLADDR));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current DMA receive descriptor pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function returns a pointer to the current Ethernet receive descriptor
|
|
|
+//! read by the DMA.
|
|
|
+//!
|
|
|
+//! \return Returns a pointer to the start of the current receive DMA
|
|
|
+//! descriptor.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+tEMACDMADescriptor *
|
|
|
+EMACRxDMACurrentDescriptorGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the address of the current receive descriptor written by the DMA.
|
|
|
+ //
|
|
|
+ return ((tEMACDMADescriptor *)HWREG(ui32Base + EMAC_O_HOSRXDESC));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current DMA receive buffer pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be called to determine which buffer the receive DMA
|
|
|
+//! engine is currently writing to.
|
|
|
+//!
|
|
|
+//! \return Returns the receive buffer address currently being written by
|
|
|
+//! the DMA engine.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint8_t *
|
|
|
+EMACRxDMACurrentBufferGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the receive buffer address currently being written by the DMA.
|
|
|
+ //
|
|
|
+ return ((uint8_t *)HWREG(ui32Base + EMAC_O_HOSRXBA));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the DMA transmit descriptor list pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pDescriptor points to the first DMA descriptor in the list to
|
|
|
+//! be passed to the transmit DMA engine.
|
|
|
+//!
|
|
|
+//! This function sets the Ethernet MAC's transmit DMA descriptor list pointer.
|
|
|
+//! The \e pDescriptor pointer must point to one or more descriptor
|
|
|
+//! structures.
|
|
|
+//!
|
|
|
+//! When multiple descriptors are provided, they can be either chained or
|
|
|
+//! unchained. Chained descriptors are indicated by setting the
|
|
|
+//! \b DES0_TX_CTRL_CHAINED or \b DES1_RX_CTRL_CHAINED bit in the relevant
|
|
|
+//! word of the transmit or receive descriptor. If this bit is clear,
|
|
|
+//! unchained descriptors are assumed.
|
|
|
+//!
|
|
|
+//! Chained descriptors use a link pointer in each descriptor to
|
|
|
+//! point to the next descriptor in the chain.
|
|
|
+//!
|
|
|
+//! Unchained descriptors are assumed to be contiguous in memory with a
|
|
|
+//! consistent offset between the start of one descriptor and the next.
|
|
|
+//! If unchained descriptors are used, the \e pvLink field in the descriptor
|
|
|
+//! becomes available to store a second buffer pointer, allowing each
|
|
|
+//! descriptor to point to two buffers rather than one. In this case,
|
|
|
+//! the \e ui32DescSkipSize parameter to EMACInit() must previously have
|
|
|
+//! been set to the number of words between the end of one descriptor and
|
|
|
+//! the start of the next. This value must be 0 in cases where a packed array
|
|
|
+//! of \b tEMACDMADescriptor structures is used. If the application wishes to
|
|
|
+//! add new state fields to the end of the descriptor structure, the skip size
|
|
|
+//! should be set to accommodate the newly sized structure.
|
|
|
+//!
|
|
|
+//! Applications are responsible for initializing all descriptor fields
|
|
|
+//! appropriately before passing the descriptor list to the hardware.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTxDMADescriptorListSet(uint32_t ui32Base, tEMACDMADescriptor *pDescriptor)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(pDescriptor);
|
|
|
+ ASSERT(((uint32_t)pDescriptor & 3) == 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the supplied address to the MACTXDLADDR register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TXDLADDR) = (uint32_t)pDescriptor;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns a pointer to the start of the DMA transmit descriptor list.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function returns a pointer to the head of the Ethernet MAC's transmit
|
|
|
+//! DMA descriptor list. This value corresponds to the pointer originally set
|
|
|
+//! using a call to EMACTxDMADescriptorListSet().
|
|
|
+//!
|
|
|
+//! \return Returns a pointer to the start of the DMA transmit descriptor list.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+tEMACDMADescriptor *
|
|
|
+EMACTxDMADescriptorListGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the current transmit DMA descriptor list pointer.
|
|
|
+ //
|
|
|
+ return ((tEMACDMADescriptor *)HWREG(ui32Base + EMAC_O_TXDLADDR));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current DMA transmit descriptor pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function returns a pointer to the current Ethernet transmit descriptor
|
|
|
+//! read by the DMA.
|
|
|
+//!
|
|
|
+//! \return Returns a pointer to the start of the current transmit DMA
|
|
|
+//! descriptor.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+tEMACDMADescriptor *
|
|
|
+EMACTxDMACurrentDescriptorGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the address of the current transmit descriptor read by the DMA.
|
|
|
+ //
|
|
|
+ return ((tEMACDMADescriptor *)HWREG(ui32Base + EMAC_O_HOSTXDESC));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current DMA transmit buffer pointer.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be called to determine which buffer the transmit DMA
|
|
|
+//! engine is currently reading from.
|
|
|
+//!
|
|
|
+//! \return Returns the transmit buffer address currently being read by the
|
|
|
+//! DMA engine.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint8_t *
|
|
|
+EMACTxDMACurrentBufferGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the transmit buffer address currently being read by the DMA.
|
|
|
+ //
|
|
|
+ return ((uint8_t *)HWREG(ui32Base + EMAC_O_HOSTXBA));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current states of the Ethernet MAC transmit and receive DMA
|
|
|
+//! engines.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be used to query the current states of the transmit and
|
|
|
+//! receive DMA engines. The return value contains two fields, one providing
|
|
|
+//! the transmit state and the other the receive state. Macros
|
|
|
+//! \b EMAC_TX_DMA_STATE() and \b EMAC_RX_DMA_STATE() may be used to
|
|
|
+//! extract these fields from the returned value. Alternatively, masks
|
|
|
+//! \b EMAC_DMA_TXSTAT_MASK and \b EMAC_DMA_RXSTAT_MASK may be used
|
|
|
+//! directly to mask out the individual states from the returned value.
|
|
|
+//!
|
|
|
+//! \return Returns the states of the transmit and receive DMA engines. These
|
|
|
+//! states are ORed together into a single word containing one of:
|
|
|
+//!
|
|
|
+//! - \b EMAC_DMA_TXSTAT_STOPPED indicating that the transmit engine is
|
|
|
+//! stopped.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_RUN_FETCH_DESC indicating that the transmit engine
|
|
|
+//! is fetching the next descriptor.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_RUN_WAIT_STATUS indicating that the transmit engine
|
|
|
+//! is waiting for status from the MAC.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_RUN_READING indicating that the transmit engine is
|
|
|
+//! currently transferring data from memory to the MAC transmit FIFO.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_RUN_CLOSE_DESC indicating that the transmit engine
|
|
|
+//! is closing the descriptor after transmission of the buffer data.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_TS_WRITE indicating that the transmit engine is
|
|
|
+//! currently writing timestamp information to the descriptor.
|
|
|
+//! - \b EMAC_DMA_TXSTAT_SUSPENDED indicating that the transmit engine is
|
|
|
+//! suspended due to the next descriptor being unavailable (owned by the host)
|
|
|
+//! or a transmit buffer underflow.
|
|
|
+//!
|
|
|
+//! and one of:
|
|
|
+//!
|
|
|
+//! - \b EMAC_DMA_RXSTAT_STOPPED indicating that the receive engine is
|
|
|
+//! stopped.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_RUN_FETCH_DESC indicating that the receive engine
|
|
|
+//! is fetching the next descriptor.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_RUN_WAIT_PACKET indicating that the receive engine
|
|
|
+//! is waiting for the next packet.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_SUSPENDED indicating that the receive engine is
|
|
|
+//! suspended due to the next descriptor being unavailable.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_RUN_CLOSE_DESC indicating that the receive engine
|
|
|
+//! is closing the descriptor after receiving a buffer of data.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_TS_WRITE indicating that the transmit engine is
|
|
|
+//! currently writing timestamp information to the descriptor.
|
|
|
+//! - \b EMAC_DMA_RXSTAT_RUN_RECEIVING indicating that the receive engine is
|
|
|
+//! currently transferring data from the MAC receive FIFO to memory.
|
|
|
+//!
|
|
|
+//! Additionally, a DMA bus error may be signaled using \b EMAC_DMA_ERROR.
|
|
|
+//! If this flag is present, the source of the error is identified using one
|
|
|
+//! of the following values which may be extracted from the return value using
|
|
|
+//! \b EMAC_DMA_ERR_MASK:
|
|
|
+//!
|
|
|
+//! - \b EMAC_DMA_ERR_RX_DATA_WRITE indicates that an error occurred when
|
|
|
+//! writing received data to memory.
|
|
|
+//! - \b EMAC_DMA_ERR_TX_DATA_READ indicates that an error occurred when
|
|
|
+//! reading data from memory for transmission.
|
|
|
+//! - \b EMAC_DMA_ERR_RX_DESC_WRITE indicates that an error occurred when
|
|
|
+//! writing to the receive descriptor.
|
|
|
+//! - \b EMAC_DMA_ERR_TX_DESC_WRITE indicates that an error occurred when
|
|
|
+//! writing to the transmit descriptor.
|
|
|
+//! - \b EMAC_DMA_ERR_RX_DESC_READ indicates that an error occurred when
|
|
|
+//! reading the receive descriptor.
|
|
|
+//! - \b EMAC_DMA_ERR_TX_DESC_READ indicates that an error occurred when
|
|
|
+//! reading the transmit descriptor.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACDMAStateGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Return the status of the DMA channels.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_DMARIS) &
|
|
|
+ (EMAC_DMARIS_FBI | EMAC_DMARIS_AE_M | EMAC_DMARIS_RS_M |
|
|
|
+ EMAC_DMARIS_TS_M));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Flushes the Ethernet controller transmit FIFO.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function flushes any data currently held in the Ethernet transmit
|
|
|
+//! FIFO. Data that has already been passed to the MAC for transmission is
|
|
|
+//! transmitted, possibly resulting in a transmit underflow or runt frame
|
|
|
+//! transmission.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTxFlush(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Check to make sure that the FIFO is not already empty.
|
|
|
+ //
|
|
|
+ if (HWREG(ui32Base + EMAC_O_STATUS) & EMAC_STATUS_TXFE)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Flush the transmit FIFO since it is not currently empty.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) |= EMAC_DMAOPMODE_FTF;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for the flush to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_DMAOPMODE) & EMAC_DMAOPMODE_FTF)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables the Ethernet controller transmitter.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! When starting operations on the Ethernet interface, this function should
|
|
|
+//! be called to enable the transmitter after all configuration has been
|
|
|
+//! completed.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTxEnable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Enable the MAC transmit path in the opmode register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) |= EMAC_DMAOPMODE_ST;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable transmission in the MAC configuration register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) |= EMAC_CFG_TE;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Disables the Ethernet controller transmitter.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! When terminating operations on the Ethernet interface, this function should
|
|
|
+//! be called. This function disables the transmitter.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTxDisable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Disable transmission in the MAC configuration register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) &= ~EMAC_CFG_TE;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable the MAC transmit path in the opmode register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) &= ~EMAC_DMAOPMODE_ST;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables the Ethernet controller receiver.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! When starting operations on the Ethernet interface, this function should
|
|
|
+//! be called to enable the receiver after all configuration has been
|
|
|
+//! completed.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRxEnable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Enable the MAC receive path.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) |= EMAC_DMAOPMODE_SR;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable receive in the MAC configuration register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) |= EMAC_CFG_RE;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Disables the Ethernet controller receiver.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! When terminating operations on the Ethernet interface, this function should
|
|
|
+//! be called. This function disables the receiver.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRxDisable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Disable reception in the MAC configuration register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) &= ~EMAC_CFG_RE;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable the MAC receive path.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) &= ~EMAC_DMAOPMODE_SR;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Registers an interrupt handler for an Ethernet interrupt.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pfnHandler is a pointer to the function to be called when the
|
|
|
+//! enabled Ethernet interrupts occur.
|
|
|
+//!
|
|
|
+//! This function sets the handler to be called when the Ethernet interrupt
|
|
|
+//! occurs. This function enables the global interrupt in the interrupt
|
|
|
+//! controller; specific Ethernet interrupts must be enabled via
|
|
|
+//! EMACIntEnable(). It is the interrupt handler's responsibility to clear
|
|
|
+//! the interrupt source.
|
|
|
+//!
|
|
|
+//! \sa IntRegister() for important information about registering interrupt
|
|
|
+//! handlers.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Check the arguments.
|
|
|
+ //
|
|
|
+ ASSERT(pfnHandler != 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Register the interrupt handler.
|
|
|
+ //
|
|
|
+ IntRegister(INT_EMAC0, pfnHandler);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable the Ethernet interrupt.
|
|
|
+ //
|
|
|
+ IntEnable(INT_EMAC0);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Unregisters an interrupt handler for an Ethernet interrupt.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function unregisters the interrupt handler. This function disables
|
|
|
+//! the global interrupt in the interrupt controller so that the interrupt
|
|
|
+//! handler is no longer called.
|
|
|
+//!
|
|
|
+//! \sa IntRegister() for important information about registering interrupt
|
|
|
+//! handlers.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACIntUnregister(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Disable the interrupt.
|
|
|
+ //
|
|
|
+ IntDisable(INT_EMAC0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Unregister the interrupt handler.
|
|
|
+ //
|
|
|
+ IntUnregister(INT_EMAC0);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables individual Ethernet MAC interrupt sources.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet MAC.
|
|
|
+//! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled.
|
|
|
+//!
|
|
|
+//! This function enables the indicated Ethernet MAC interrupt sources. Only
|
|
|
+//! the sources that are enabled can be reflected to the processor interrupt;
|
|
|
+//! disabled sources have no effect on the processor.
|
|
|
+//!
|
|
|
+//! The \e ui32IntFlags parameter is the logical OR of any of the following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_INT_PHY indicates that the PHY has signaled a change of state.
|
|
|
+//! Software must read and write the appropriate PHY registers to enable and
|
|
|
+//! disable particular notifications.
|
|
|
+//! - \b EMAC_INT_EARLY_RECEIVE indicates that the DMA engine has filled the
|
|
|
+//! first data buffer of a packet.
|
|
|
+//! - \b EMAC_INT_BUS_ERROR indicates that a fatal bus error has occurred and
|
|
|
+//! that the DMA engine has been disabled.
|
|
|
+//! - \b EMAC_INT_EARLY_TRANSMIT indicates that a frame to be transmitted has
|
|
|
+//! been fully written from memory into the MAC transmit FIFO.
|
|
|
+//! - \b EMAC_INT_RX_WATCHDOG indicates that a frame with length greater than
|
|
|
+//! 2048 bytes (of 10240 bytes in Jumbo Frame mode) was received.
|
|
|
+//! - \b EMAC_INT_RX_STOPPED indicates that the receive process has entered
|
|
|
+//! the stopped state.
|
|
|
+//! - \b EMAC_INT_RX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's receive descriptor list and the DMA cannot, therefore, acquire
|
|
|
+//! a buffer. The receive process is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACRxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_RECEIVE indicates that reception of a frame has completed
|
|
|
+//! and all requested status has been written to the appropriate DMA receive
|
|
|
+//! descriptor.
|
|
|
+//! - \b EMAC_INT_TX_UNDERFLOW indicates that the transmitter experienced an
|
|
|
+//! underflow during transmission. The transmit process is suspended.
|
|
|
+//! - \b EMAC_INT_RX_OVERFLOW indicates that an overflow was experienced
|
|
|
+//! during reception.
|
|
|
+//! - \b EMAC_INT_TX_JABBER indicates that the transmit jabber timer expired.
|
|
|
+//! This condition occurs when the frame size exceeds 2048 bytes (or 10240
|
|
|
+//! bytes in Jumbo Frame mode) and causes the transmit process to abort and
|
|
|
+//! enter the Stopped state.
|
|
|
+//! - \b EMAC_INT_TX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's transmit descriptor list and that the DMA cannot, therefore,
|
|
|
+//! acquire a buffer. Transmission is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACTxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_TX_STOPPED indicates that the transmit process has stopped.
|
|
|
+//! - \b EMAC_INT_TRANSMIT indicates that transmission of a frame has
|
|
|
+//! completed and that all requested status has been updated in the descriptor.
|
|
|
+//!
|
|
|
+//! Summary interrupt bits \b EMAC_INT_NORMAL_INT and
|
|
|
+//! \b EMAC_INT_ABNORMAL_INT are enabled automatically by the driver if any
|
|
|
+//! of their constituent sources are enabled. Applications do not need to
|
|
|
+//! explicitly enable these bits.
|
|
|
+//!
|
|
|
+//! \note Timestamp-related interrupts from the IEEE 1588 module must be
|
|
|
+//! enabled independently by using a call to EMACTimestampTargetIntEnable().
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT((ui32IntFlags & ~EMAC_MASKABLE_INTS) == 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable the normal interrupt if any of its individual sources are
|
|
|
+ // enabled.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_NORMAL_INTS)
|
|
|
+ {
|
|
|
+ ui32IntFlags |= EMAC_INT_NORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Similarly, enable the abnormal interrupt if any of its individual
|
|
|
+ // sources are enabled.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_ABNORMAL_INTS)
|
|
|
+ {
|
|
|
+ ui32IntFlags |= EMAC_INT_ABNORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the MAC DMA interrupt mask appropriately if any of the sources
|
|
|
+ // we've been asked to enable are found in that register.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & ~EMAC_INT_PHY)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAIM) |= ui32IntFlags & ~EMAC_INT_PHY;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable the PHY interrupt if we've been asked to do this.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_INT_PHY)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_EPHYIM) |= EMAC_EPHYIM_INT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Disables individual Ethernet MAC interrupt sources.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet MAC.
|
|
|
+//! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled.
|
|
|
+//!
|
|
|
+//! This function disables the indicated Ethernet MAC interrupt sources.
|
|
|
+//!
|
|
|
+//! The \e ui32IntFlags parameter is the logical OR of any of the following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_INT_PHY indicates that the PHY has signaled a change of state.
|
|
|
+//! Software must read and write the appropriate PHY registers to enable and
|
|
|
+//! disable particular notifications.
|
|
|
+//! - \b EMAC_INT_EARLY_RECEIVE indicates that the DMA engine has filled the
|
|
|
+//! first data buffer of a packet.
|
|
|
+//! - \b EMAC_INT_BUS_ERROR indicates that a fatal bus error has occurred and
|
|
|
+//! that the DMA engine has been disabled.
|
|
|
+//! - \b EMAC_INT_EARLY_TRANSMIT indicates that a frame to be transmitted has
|
|
|
+//! been fully written from memory into the MAC transmit FIFO.
|
|
|
+//! - \b EMAC_INT_RX_WATCHDOG indicates that a frame with length greater than
|
|
|
+//! 2048 bytes (of 10240 bytes in Jumbo Frame mode) was received.
|
|
|
+//! - \b EMAC_INT_RX_STOPPED indicates that the receive process has entered
|
|
|
+//! the stopped state.
|
|
|
+//! - \b EMAC_INT_RX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's receive descriptor list and the DMA cannot, therefore, acquire
|
|
|
+//! a buffer. The receive process is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACRxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_RECEIVE indicates that reception of a frame has completed
|
|
|
+//! and all requested status has been written to the appropriate DMA receive
|
|
|
+//! descriptor.
|
|
|
+//! - \b EMAC_INT_TX_UNDERFLOW indicates that the transmitter experienced an
|
|
|
+//! underflow during transmission. The transmit process is suspended.
|
|
|
+//! - \b EMAC_INT_RX_OVERFLOW indicates that an overflow was experienced
|
|
|
+//! during reception.
|
|
|
+//! - \b EMAC_INT_TX_JABBER indicates that the transmit jabber timer expired.
|
|
|
+//! This condition occurs when the frame size exceeds 2048 bytes (or 10240
|
|
|
+//! bytes in Jumbo Frame mode) and causes the transmit process to abort and
|
|
|
+//! enter the Stopped state.
|
|
|
+//! - \b EMAC_INT_TX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's transmit descriptor list and that the DMA cannot, therefore,
|
|
|
+//! acquire a buffer. Transmission is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACTxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_TX_STOPPED indicates that the transmit process has stopped.
|
|
|
+//! - \b EMAC_INT_TRANSMIT indicates that transmission of a frame has
|
|
|
+//! completed and that all requested status has been updated in the descriptor.
|
|
|
+//! - \b EMAC_INT_TIMESTAMP indicates that an interrupt from the timestamp
|
|
|
+//! module has occurred. This precise source of the interrupt can be
|
|
|
+//! determined by calling EMACTimestampIntStatus(), which also clears this
|
|
|
+//! bit.
|
|
|
+//!
|
|
|
+//! Summary interrupt bits \b EMAC_INT_NORMAL_INT and
|
|
|
+//! \b EMAC_INT_ABNORMAL_INT are disabled automatically by the driver if none
|
|
|
+//! of their constituent sources are enabled. Applications do not need to
|
|
|
+//! explicitly disable these bits.
|
|
|
+//!
|
|
|
+//! \note Timestamp-related interrupts from the IEEE 1588 module must be
|
|
|
+//! disabled independently by using a call to EMACTimestampTargetIntDisable().
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
|
|
|
+{
|
|
|
+ uint32_t ui32Mask;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT((ui32IntFlags & ~EMAC_MASKABLE_INTS) == 0);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the current interrupt mask.
|
|
|
+ //
|
|
|
+ ui32Mask = HWREG(ui32Base + EMAC_O_DMAIM);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Clear the requested bits.
|
|
|
+ //
|
|
|
+ ui32Mask &= ~(ui32IntFlags & ~EMAC_INT_PHY);
|
|
|
+
|
|
|
+ //
|
|
|
+ // If none of the normal interrupt sources are enabled, disable the
|
|
|
+ // normal interrupt.
|
|
|
+ //
|
|
|
+ if (!(ui32Mask & EMAC_NORMAL_INTS))
|
|
|
+ {
|
|
|
+ ui32Mask &= ~EMAC_INT_NORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Similarly, if none of the abnormal interrupt sources are enabled,
|
|
|
+ // disable the abnormal interrupt.
|
|
|
+ //
|
|
|
+ if (!(ui32Mask & EMAC_ABNORMAL_INTS))
|
|
|
+ {
|
|
|
+ ui32Mask &= ~EMAC_INT_ABNORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the new mask back to the hardware.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAIM) = ui32Mask;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable the PHY interrupt if we've been asked to do this.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_INT_PHY)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_EPHYIM) &= ~EMAC_EPHYIM_INT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Gets the current Ethernet MAC interrupt status.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet MAC.
|
|
|
+//! \param bMasked is \b true to return the masked interrupt status or \b false
|
|
|
+//! to return the unmasked status.
|
|
|
+//!
|
|
|
+//! This function returns the interrupt status for the Ethernet MAC. Either
|
|
|
+//! the raw interrupt status or the status of interrupts that are allowed
|
|
|
+//! to reflect to the processor can be returned.
|
|
|
+//!
|
|
|
+//! \return Returns the current interrupt status as the logical OR of any of
|
|
|
+//! the following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_INT_PHY indicates that the PHY interrupt has occurred.
|
|
|
+//! Software must read the relevant PHY interrupt status register to determine
|
|
|
+//! the cause.
|
|
|
+//! - \b EMAC_INT_EARLY_RECEIVE indicates that the DMA engine has filled the
|
|
|
+//! first data buffer of a packet.
|
|
|
+//! - \b EMAC_INT_BUS_ERROR indicates that a fatal bus error has occurred and
|
|
|
+//! that the DMA engine has been disabled. The cause of the error can be
|
|
|
+//! determined by calling EMACDMAStateGet().
|
|
|
+//! - \b EMAC_INT_EARLY_TRANSMIT indicates that a frame to be transmitted has
|
|
|
+//! been fully written from memory into the MAC transmit FIFO.
|
|
|
+//! - \b EMAC_INT_RX_WATCHDOG indicates that a frame with length greater than
|
|
|
+//! 2048 bytes (of 10240 bytes in Jumbo Frame mode) was received.
|
|
|
+//! - \b EMAC_INT_RX_STOPPED indicates that the receive process has entered
|
|
|
+//! the stopped state.
|
|
|
+//! - \b EMAC_INT_RX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's receive descriptor list and the DMA cannot, therefore, acquire
|
|
|
+//! a buffer. The receive process is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACRxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_RECEIVE indicates that reception of a frame has completed
|
|
|
+//! and all requested status has been written to the appropriate DMA receive
|
|
|
+//! descriptor.
|
|
|
+//! - \b EMAC_INT_TX_UNDERFLOW indicates that the transmitter experienced an
|
|
|
+//! underflow during transmission. The transmit process is suspended.
|
|
|
+//! - \b EMAC_INT_RX_OVERFLOW indicates that an overflow was experienced
|
|
|
+//! during reception.
|
|
|
+//! - \b EMAC_INT_TX_JABBER indicates that the transmit jabber timer expired.
|
|
|
+//! This condition occurs when the frame size exceeds 2048 bytes (or 10240
|
|
|
+//! bytes in Jumbo Frame mode) and causes the transmit process to abort and
|
|
|
+//! enter the Stopped state.
|
|
|
+//! - \b EMAC_INT_TX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's transmit descriptor list and that the DMA cannot, therefore,
|
|
|
+//! acquire a buffer. Transmission is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACTxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_TX_STOPPED indicates that the transmit process has stopped.
|
|
|
+//! - \b EMAC_INT_TRANSMIT indicates that transmission of a frame has
|
|
|
+//! completed and that all requested status has been updated in the descriptor.
|
|
|
+//! - \b EMAC_INT_NORMAL_INT is a summary interrupt comprising the logical
|
|
|
+//! OR of the masked state of \b EMAC_INT_TRANSMIT, \b EMAC_INT_RECEIVE,
|
|
|
+//! \b EMAC_INT_TX_NO_BUFFER and \b EMAC_INT_EARLY_RECEIVE.
|
|
|
+//! - \b EMAC_INT_ABNORMAL_INT is a summary interrupt comprising the logical
|
|
|
+//! OR of the masked state of \b EMAC_INT_TX_STOPPED, \b EMAC_INT_TX_JABBER,
|
|
|
+//! \b EMAC_INT_RX_OVERFLOW, \b EMAC_INT_TX_UNDERFLOW,
|
|
|
+//! \b EMAC_INT_RX_NO_BUFFER, \b EMAC_INT_RX_STOPPED,
|
|
|
+//! \b EMAC_INT_RX_WATCHDOG, \b EMAC_INT_EARLY_TRANSMIT and
|
|
|
+//! \b EMAC_INT_BUS_ERROR.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACIntStatus(uint32_t ui32Base, bool bMasked)
|
|
|
+{
|
|
|
+ uint32_t ui32Val, ui32PHYStat;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get the unmasked interrupt status and clear any unwanted status fields.
|
|
|
+ //
|
|
|
+ ui32Val = HWREG(ui32Base + EMAC_O_DMARIS);
|
|
|
+ ui32Val &= ~(EMAC_DMARIS_AE_M | EMAC_DMARIS_TS_M | EMAC_DMARIS_RS_M);
|
|
|
+
|
|
|
+ //
|
|
|
+ // This peripheral doesn't have a masked interrupt status register
|
|
|
+ // so perform the masking manually. Note that only the bottom 16 bits
|
|
|
+ // of the register can be masked so make sure we take this into account.
|
|
|
+ //
|
|
|
+ if (bMasked)
|
|
|
+ {
|
|
|
+ ui32Val &= (EMAC_NON_MASKED_INTS | HWREG(ui32Base + EMAC_O_DMAIM));
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the PHY interrupt status.
|
|
|
+ //
|
|
|
+ if (bMasked)
|
|
|
+ {
|
|
|
+ ui32PHYStat = HWREG(ui32Base + EMAC_O_EPHYMISC);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ui32PHYStat = HWREG(ui32Base + EMAC_O_EPHYRIS);
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // If the PHY interrupt is reported, add the appropriate flag to the
|
|
|
+ // return value.
|
|
|
+ //
|
|
|
+ if (ui32PHYStat & EMAC_EPHYMISC_INT)
|
|
|
+ {
|
|
|
+ ui32Val |= EMAC_INT_PHY;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (ui32Val);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Clears individual Ethernet MAC interrupt sources.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the Ethernet MAC.
|
|
|
+//! \param ui32IntFlags is the bit mask of the interrupt sources to be cleared.
|
|
|
+//!
|
|
|
+//! This function disables the indicated Ethernet MAC interrupt sources.
|
|
|
+//!
|
|
|
+//! The \e ui32IntFlags parameter is the logical OR of any of the following:
|
|
|
+//!
|
|
|
+//! - \b EMAC_INT_PHY indicates that the PHY has signaled a change of state.
|
|
|
+//! Software must read and write the appropriate PHY registers to enable,
|
|
|
+//! disable and clear particular notifications.
|
|
|
+//! - \b EMAC_INT_EARLY_RECEIVE indicates that the DMA engine has filled the
|
|
|
+//! first data buffer of a packet.
|
|
|
+//! - \b EMAC_INT_BUS_ERROR indicates that a fatal bus error has occurred and
|
|
|
+//! that the DMA engine has been disabled.
|
|
|
+//! - \b EMAC_INT_EARLY_TRANSMIT indicates that a frame to be transmitted has
|
|
|
+//! been fully written from memory into the MAC transmit FIFO.
|
|
|
+//! - \b EMAC_INT_RX_WATCHDOG indicates that a frame with length greater than
|
|
|
+//! 2048 bytes (of 10240 bytes in Jumbo Frame mode) was received.
|
|
|
+//! - \b EMAC_INT_RX_STOPPED indicates that the receive process has entered
|
|
|
+//! the stopped state.
|
|
|
+//! - \b EMAC_INT_RX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's receive descriptor list and the DMA cannot, therefore, acquire
|
|
|
+//! a buffer. The receive process is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACRxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_RECEIVE indicates that reception of a frame has completed
|
|
|
+//! and all requested status has been written to the appropriate DMA receive
|
|
|
+//! descriptor.
|
|
|
+//! - \b EMAC_INT_TX_UNDERFLOW indicates that the transmitter experienced an
|
|
|
+//! underflow during transmission. The transmit process is suspended.
|
|
|
+//! - \b EMAC_INT_RX_OVERFLOW indicates that an overflow was experienced
|
|
|
+//! during reception.
|
|
|
+//! - \b EMAC_INT_TX_JABBER indicates that the transmit jabber timer expired.
|
|
|
+//! This condition occurs when the frame size exceeds 2048 bytes (or 10240
|
|
|
+//! bytes in Jumbo Frame mode) and causes the transmit process to abort and
|
|
|
+//! enter the Stopped state.
|
|
|
+//! - \b EMAC_INT_TX_NO_BUFFER indicates that the host owns the next buffer
|
|
|
+//! in the DMA's transmit descriptor list and that the DMA cannot, therefore,
|
|
|
+//! acquire a buffer. Transmission is suspended and can be resumed by changing
|
|
|
+//! the descriptor ownership and calling EMACTxDMAPollDemand().
|
|
|
+//! - \b EMAC_INT_TX_STOPPED indicates that the transmit process has stopped.
|
|
|
+//! - \b EMAC_INT_TRANSMIT indicates that transmission of a frame has
|
|
|
+//! completed and that all requested status has been updated in the descriptor.
|
|
|
+//!
|
|
|
+//! Summary interrupt bits \b EMAC_INT_NORMAL_INT and
|
|
|
+//! \b EMAC_INT_ABNORMAL_INT are cleared automatically by the driver if any
|
|
|
+//! of their constituent sources are cleared. Applications do not need to
|
|
|
+//! explicitly clear these bits.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACIntClear(uint32_t ui32Base, uint32_t ui32IntFlags)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Mask in the normal interrupt if one of the sources it relates to is
|
|
|
+ // specified.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_NORMAL_INTS)
|
|
|
+ {
|
|
|
+ ui32IntFlags |= EMAC_INT_NORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Similarly, mask in the abnormal interrupt if one of the sources it
|
|
|
+ // relates to is specified.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_ABNORMAL_INTS)
|
|
|
+ {
|
|
|
+ ui32IntFlags |= EMAC_INT_ABNORMAL_INT;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Clear the maskable interrupt sources. We write exactly the value passed
|
|
|
+ // (with the summary sources added if necessary) but remember that only
|
|
|
+ // the bottom 17 bits of the register are actually clearable. Only do
|
|
|
+ // this if some bits are actually set that refer to the DMA interrupt
|
|
|
+ // sources.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & ~EMAC_INT_PHY)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_DMARIS) = (ui32IntFlags & ~EMAC_INT_PHY);
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Clear the PHY interrupt if we've been asked to do this.
|
|
|
+ //
|
|
|
+ if (ui32IntFlags & EMAC_INT_PHY)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_EPHYMISC) |= EMAC_EPHYMISC_INT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Writes to the PHY register.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui8RegAddr is the address of the PHY register to be accessed.
|
|
|
+//! \param ui16Data is the data to be written to the PHY register.
|
|
|
+//!
|
|
|
+//! This function writes the \e ui16Data value to the PHY register specified by
|
|
|
+//! \e ui8RegAddr.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYWrite(uint32_t ui32Base, uint8_t ui8PhyAddr, uint8_t ui8RegAddr,
|
|
|
+ uint16_t ui16Data)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Make sure the MII is idle.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the value provided.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_MIIDATA) = ui16Data;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Tell the MAC to write the given PHY register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_MIIADDR) =
|
|
|
+ ((HWREG(ui32Base + EMAC_O_MIIADDR) &
|
|
|
+ EMAC_MIIADDR_CR_M) | (ui8RegAddr << EMAC_MIIADDR_MII_S) |
|
|
|
+ (ui8PhyAddr << EMAC_MIIADDR_PLA_S) | EMAC_MIIADDR_MIIW |
|
|
|
+ EMAC_MIIADDR_MIIB);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for the write to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB)
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Reads from a PHY register.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui8RegAddr is the address of the PHY register to be accessed.
|
|
|
+//!
|
|
|
+//! This function returns the contents of the PHY register specified by
|
|
|
+//! \e ui8RegAddr.
|
|
|
+//!
|
|
|
+//! \return Returns the 16-bit value read from the PHY.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint16_t
|
|
|
+EMACPHYRead(uint32_t ui32Base, uint8_t ui8PhyAddr, uint8_t ui8RegAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Make sure the MII is idle.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Tell the MAC to read the given PHY register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_MIIADDR) =
|
|
|
+ ((HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_CR_M) |
|
|
|
+ (ui8RegAddr << EMAC_MIIADDR_MII_S) |
|
|
|
+ (ui8PhyAddr << EMAC_MIIADDR_PLA_S) | EMAC_MIIADDR_MIIB);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for the read to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_MIIADDR) & EMAC_MIIADDR_MIIB)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the result.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_MIIDATA) & EMAC_MIIDATA_DATA_M);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Reads from an extended PHY register.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui16RegAddr is the address of the PHY extended register to be
|
|
|
+//! accessed.
|
|
|
+//!
|
|
|
+//! When using the internal PHY or when connected to an external PHY
|
|
|
+//! supporting extended registers, this function returns the contents of the
|
|
|
+//! extended PHY register specified by \e ui16RegAddr.
|
|
|
+//!
|
|
|
+//! \return Returns the 16-bit value read from the PHY.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint16_t
|
|
|
+EMACPHYExtendedRead(uint32_t ui32Base, uint8_t ui8PhyAddr,
|
|
|
+ uint16_t ui16RegAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the address of the register we're about to read.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_REGCTL, 0x001F);
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_ADDAR, ui16RegAddr);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the extended register value.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_REGCTL, 0x401F);
|
|
|
+ return (EMACPHYRead(EMAC0_BASE, ui8PhyAddr, EPHY_ADDAR));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Writes a value to an extended PHY register.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui16RegAddr is the address of the PHY extended register to be
|
|
|
+//! accessed.
|
|
|
+//! \param ui16Value is the value to write to the register.
|
|
|
+//!
|
|
|
+//! When using the internal PHY or when connected to an external PHY
|
|
|
+//! supporting extended registers, this function allows a value to be written
|
|
|
+//! to the extended PHY register specified by \e ui16RegAddr.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYExtendedWrite(uint32_t ui32Base, uint8_t ui8PhyAddr,
|
|
|
+ uint16_t ui16RegAddr, uint16_t ui16Value)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the address of the register we're about to write.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_REGCTL, 0x001F);
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_ADDAR, ui16RegAddr);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the extended register.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_REGCTL, 0x401F);
|
|
|
+ EMACPHYWrite(EMAC0_BASE, ui8PhyAddr, EPHY_ADDAR, ui16Value);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Powers off the Ethernet PHY.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to power down.
|
|
|
+//!
|
|
|
+//! This function powers off the Ethernet PHY, reducing the current
|
|
|
+//! consumption of the device. While in the powered-off state, the Ethernet
|
|
|
+//! controller is unable to connect to Ethernet.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYPowerOff(uint32_t ui32Base, uint8_t ui8PhyAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Set the PWRDN bit and clear the ANEN bit in the PHY, putting it into
|
|
|
+ // its low power mode.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_BMCR,
|
|
|
+ (EMACPHYRead(ui32Base, ui8PhyAddr, EPHY_BMCR) &
|
|
|
+ ~EPHY_BMCR_ANEN) | EPHY_BMCR_PWRDWN);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Powers on the Ethernet PHY.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to power up.
|
|
|
+//!
|
|
|
+//! This function powers on the Ethernet PHY, enabling it return to normal
|
|
|
+//! operation. By default, the PHY is powered on, so this function is only
|
|
|
+//! called if EMACPHYPowerOff() has previously been called.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYPowerOn(uint32_t ui32Base, uint8_t ui8PhyAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Clear the PWRDN bit and set the ANEGEN bit in the PHY, putting it into
|
|
|
+ // normal operating mode.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_BMCR,
|
|
|
+ (EMACPHYRead(ui32Base, ui8PhyAddr, EPHY_BMCR) &
|
|
|
+ ~EPHY_BMCR_PWRDWN) | EPHY_BMCR_ANEN);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Configures the Ethernet MAC's IEEE 1588 timestamping options.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Config contains flags selecting particular configuration
|
|
|
+//! options.
|
|
|
+//! \param ui32SubSecondInc is the number that the IEEE 1588 subsecond clock
|
|
|
+//! should increment on each tick.
|
|
|
+//!
|
|
|
+//! This function is used to configure the operation of the Ethernet MAC's
|
|
|
+//! internal timestamping clock. This clock is used to timestamp incoming
|
|
|
+//! and outgoing packets and as an accurate system time reference when
|
|
|
+//! IEEE 1588 Precision Time Protocol is in use.
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter contains a collection of flags selecting the
|
|
|
+//! desired options. Valid flags are:
|
|
|
+//!
|
|
|
+//! One of the following to determine whether IEEE 1588 version 1 or version 2
|
|
|
+//! packet format is to be processed:
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_PTP_VERSION_2
|
|
|
+//! - \b EMAC_TS_PTP_VERSION_1
|
|
|
+//!
|
|
|
+//! One of the following to determine how the IEEE 1588 clock's subsecond
|
|
|
+//! value should be interpreted and handled:
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_DIGITAL_ROLLOVER causes the clock's subsecond value to roll
|
|
|
+//! over at 0x3BA9C9FF (999999999 decimal). In this mode, it can be considered
|
|
|
+//! as a nanosecond counter with each digit representing 1 ns.
|
|
|
+//! - \b EMAC_TS_BINARY_ROLLOVER causes the clock's subsecond value to roll
|
|
|
+//! over at 0x7FFFFFFF. In this mode, the subsecond value counts 0.465 ns
|
|
|
+//! periods.
|
|
|
+//!
|
|
|
+//! One of the following to enable or disable MAC address filtering. When
|
|
|
+//! enabled, PTP frames are filtered unless the destination MAC address matches
|
|
|
+//! any of the currently programmed MAC addresses.
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_MAC_FILTER_ENABLE
|
|
|
+//! - \b EMAC_TS_MAC_FILTER_DISABLE
|
|
|
+//!
|
|
|
+//! One of the following to determine how the clock is updated:
|
|
|
+//! - \b EMAC_TS_UPDATE_COARSE causes the IEEE 1588 clock to advance by
|
|
|
+//! the value supplied in the \e ui32SubSecondInc parameter on each main
|
|
|
+//! oscillator clock cycle.
|
|
|
+//! - \b EMAC_TS_UPDATE_FINE selects the fine update method which causes the
|
|
|
+//! IEEE 1588 clock to advance by the the value supplied in the
|
|
|
+//! \e ui32SubSecondInc parameter each time a carry is generated from the
|
|
|
+//! addend accumulator register.
|
|
|
+//!
|
|
|
+//! One of the following to determine which IEEE 1588 messages are timestamped:
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_SYNC_FOLLOW_DREQ_DRESP timestamps SYNC, Follow_Up, Delay_Req
|
|
|
+//! and Delay_Resp messages.
|
|
|
+//! - \b EMAC_TS_SYNC_ONLY timestamps only SYNC messages.
|
|
|
+//! - \b EMAC_TS_DELAYREQ_ONLY timestamps only Delay_Req messages.
|
|
|
+//! - \b EMAC_TS_ALL timestamps all IEEE 1588 messages.
|
|
|
+//! - \b EMAC_TS_SYNC_PDREQ_PDRESP timestamps only SYNC, Pdelay_Req and
|
|
|
+//! Pdelay_Resp messages.
|
|
|
+//! - \b EMAC_TS_DREQ_PDREQ_PDRESP timestamps only Delay_Req, Pdelay_Req and
|
|
|
+//! Pdelay_Resp messages.
|
|
|
+//! - \b EMAC_TS_SYNC_DELAYREQ timestamps only Delay_Req messages.
|
|
|
+//! - \b EMAC_TS_PDREQ_PDRESP timestamps only Pdelay_Req and Pdelay_Resp
|
|
|
+//! messages.
|
|
|
+//!
|
|
|
+//! Optional, additional flags are:
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_PROCESS_IPV4_UDP processes PTP packets encapsulated in UDP
|
|
|
+//! over IPv4 packets. If absent, the MAC ignores these frames.
|
|
|
+//! - \b EMAC_TS_PROCESS_IPV6_UDP processes PTP packets encapsulated in UDP
|
|
|
+//! over IPv6 packets. If absent, the MAC ignores these frames.
|
|
|
+//! - \b EMAC_TS_PROCESS_ETHERNET processes PTP packets encapsulated directly
|
|
|
+//! in Ethernet frames. If absent, the MAC ignores these frames.
|
|
|
+//! - \b EMAC_TS_ALL_RX_FRAMES enables timestamping for all frames received
|
|
|
+//! by the MAC, regardless of type.
|
|
|
+//!
|
|
|
+//! The \e ui32SubSecondInc controls the rate at which the timestamp clock's
|
|
|
+//! subsecond count increments. Its meaning depends on which of \b
|
|
|
+//! EMAC_TS_DIGITAL_ROLLOVER or \b EMAC_TS_BINARY_ROLLOVER and
|
|
|
+//! \b EMAC_TS_UPDATE_FINE or \b EMAC_TS_UPDATE_COARSE were included
|
|
|
+//! in \e ui32Config.
|
|
|
+//!
|
|
|
+//! The timestamp second counter is incremented each time the subsecond counter
|
|
|
+//! rolls over. In digital rollover mode, the subsecond counter acts as a
|
|
|
+//! simple 31-bit counter, rolling over to 0 after reaching 0x7FFFFFFF. In
|
|
|
+//! this case, each lsb of the subsecond counter represents 0.465 ns (assuming
|
|
|
+//! the definition of 1 second resolution for the seconds counter). When
|
|
|
+//! binary rollover mode is selected, the subsecond counter acts as a
|
|
|
+//! nanosecond counter and rolls over to 0 after reaching 999,999,999 making
|
|
|
+//! each lsb represent 1 nanosecond.
|
|
|
+//!
|
|
|
+//! In coarse update mode, the timestamp subsecond counter is incremented by
|
|
|
+//! \e ui32SubSecondInc on each main oscillator clock tick. Setting
|
|
|
+//! \e ui32SubSecondInc to the main oscillator clock period in either 1 ns or
|
|
|
+//! 0.465 ns units ensures that the time stamp, read as seconds and
|
|
|
+//! subseconds, increments at the same rate as the main oscillator clock. For
|
|
|
+//! example, if the main oscillator is 25 MHz, \e ui32SubSecondInc is set to 40
|
|
|
+//! if digital rollover mode is selected or (40 / 0.465) = 86 in binary
|
|
|
+//! rollover mode.
|
|
|
+//!
|
|
|
+//! In fine update mode, the subsecond increment value must be set according
|
|
|
+//! to the desired accuracy of the recovered IEEE 1588 clock which must be
|
|
|
+//! lower than the system clock rate. Fine update mode is typically used when
|
|
|
+//! synchronizing the local clock to the IEEE 1588 master clock. The subsecond
|
|
|
+//! counter is incremented by \e ui32SubSecondInc counts each time a 32-bit
|
|
|
+//! accumulator register generates a carry. The accumulator register is
|
|
|
+//! incremented by the addend value on each main oscillator tick and this
|
|
|
+//! addend value is modified to allow fine control over the rate of change of
|
|
|
+//! the timestamp counter. The addend value is calculated using the ratio of
|
|
|
+//! the main oscillator clock rate and the desired IEEE 1588 clock rate and the
|
|
|
+//! \e ui32SubSecondInc value is set to correspond to the desired IEEE 1588
|
|
|
+//! clock rate. As an example, using digital rollover mode and a 25-MHz
|
|
|
+//! main oscillator clock with a desired IEEE 1588 clock accuracy of 12.5 MHz,
|
|
|
+//! we would set \e ui32SubSecondInc to the 12.5-MHz clock period of 80 ns and
|
|
|
+//! set the initial addend value to 0x80000000 to generate a carry on every
|
|
|
+//! second system clock.
|
|
|
+//!
|
|
|
+//! \sa EMACTimestampAddendSet()
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampConfigSet(uint32_t ui32Base, uint32_t ui32Config,
|
|
|
+ uint32_t ui32SubSecondInc)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Ensure that the PTP module clock is enabled.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CC) |= EMAC_CC_PTPCEN;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the subsecond increment value.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_SUBSECINC) = ((ui32SubSecondInc <<
|
|
|
+ EMAC_SUBSECINC_SSINC_S) &
|
|
|
+ EMAC_SUBSECINC_SSINC_M);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the timestamp configuration.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) = ui32Config;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current IEEE 1588 timestamping configuration.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pui32SubSecondInc points to storage that is written with the
|
|
|
+//! current subsecond increment value for the IEEE 1588 clock.
|
|
|
+//!
|
|
|
+//! This function may be used to retreive the current MAC timestamping
|
|
|
+//! configuration.
|
|
|
+//!
|
|
|
+//! \sa EMACTimestampConfigSet()
|
|
|
+//!
|
|
|
+//! \return Returns the current timestamping configuration as a logical OR of
|
|
|
+//! the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_PTP_VERSION_2 indicates that the MAC is processing PTP
|
|
|
+//! version 2 messages. If this flag is absent, PTP version 1 messages are
|
|
|
+//! expected.
|
|
|
+//! - \b EMAC_TS_DIGITAL_ROLLOVER causes the clock's subsecond value to roll
|
|
|
+//! over at 0x3BA9C9FF (999999999 decimal). In this mode, it can be considered
|
|
|
+//! as a nanosecond counter with each digit representing 1 ns. If this flag is
|
|
|
+//! absent, the subsecond value rolls over at 0x7FFFFFFF, effectively counting
|
|
|
+//! increments of 0.465 ns.
|
|
|
+//! - \b EMAC_TS_MAC_FILTER_ENABLE indicates that incoming PTP messages
|
|
|
+//! are filtered using any of the configured MAC addresses. Messages with a
|
|
|
+//! destination address programmed into the MAC address filter are passed,
|
|
|
+//! others are discarded. If this flag is absent, the MAC address is ignored.
|
|
|
+//! - \b EMAC_TS_UPDATE_FINE implements the fine update method that causes the
|
|
|
+//! IEEE 1588 clock to advance by the the value returned in the
|
|
|
+//! \e *pui32SubSecondInc parameter each time a carry is generated from the
|
|
|
+//! addend accumulator register. If this flag is absent, the coarse update
|
|
|
+//! method is in use and the clock is advanced by the \e *pui32SubSecondInc
|
|
|
+//! value on each system clock tick.
|
|
|
+//! - \b EMAC_TS_SYNC_ONLY indicates that timestamps are only generated for
|
|
|
+//! SYNC messages.
|
|
|
+//! - \b EMAC_TS_DELAYREQ_ONLY indicates that timestamps are only generated
|
|
|
+//! for Delay_Req messages.
|
|
|
+//! - \b EMAC_TS_ALL indicates that timestamps are generated for all
|
|
|
+//! IEEE 1588 messages.
|
|
|
+//! - \b EMAC_TS_SYNC_PDREQ_PDRESP timestamps only SYNC, Pdelay_Req and
|
|
|
+//! Pdelay_Resp messages.
|
|
|
+//! - \b EMAC_TS_DREQ_PDREQ_PDRESP indicates that timestamps are only
|
|
|
+//! generated for Delay_Req, Pdelay_Req and Pdelay_Resp messages.
|
|
|
+//! - \b EMAC_TS_SYNC_DELAYREQ indicates that timestamps are only generated
|
|
|
+//! for Delay_Req messages.
|
|
|
+//! - \b EMAC_TS_PDREQ_PDRESP indicates that timestamps are only generated
|
|
|
+//! for Pdelay_Req and Pdelay_Resp messages.
|
|
|
+//! - \b EMAC_TS_PROCESS_IPV4_UDP indicates that PTP packets encapsulated in
|
|
|
+//! UDP over IPv4 packets are being processed. If absent, the MAC ignores
|
|
|
+//! these frames.
|
|
|
+//! - \b EMAC_TS_PROCESS_IPV6_UDP indicates that PTP packets encapsulated in
|
|
|
+//! UDP over IPv6 packets are being processed. If absent, the MAC ignores
|
|
|
+//! these frames.
|
|
|
+//! - \b EMAC_TS_PROCESS_ETHERNET indicates that PTP packets encapsulated
|
|
|
+//! directly in Ethernet frames are being processd. If absent, the MAC ignores
|
|
|
+//! these frames.
|
|
|
+//! - \b EMAC_TS_ALL_RX_FRAMES indicates that timestamping is enabled for all
|
|
|
+//! frames received by the MAC, regardless of type.
|
|
|
+//!
|
|
|
+//! If \b EMAC_TS_ALL_RX_FRAMES and none of the options specifying subsets
|
|
|
+//! of PTP packets to timestamp are set, the MAC is configured to timestamp
|
|
|
+//! SYNC, Follow_Up, Delay_Req and Delay_Resp messages only.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACTimestampConfigGet(uint32_t ui32Base, uint32_t *pui32SubSecondInc)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pui32SubSecondInc);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the current subsecond increment value.
|
|
|
+ //
|
|
|
+ *pui32SubSecondInc = (HWREG(ui32Base + EMAC_O_SUBSECINC) &
|
|
|
+ EMAC_SUBSECINC_SSINC_M) >> EMAC_SUBSECINC_SSINC_S;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the current timestamp configuration.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_TIMSTCTRL));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables packet timestamping and starts the system clock running.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to enable the system clock used to timestamp
|
|
|
+//! Ethernet frames and to enable that timestamping.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampEnable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Enable IEEE 1588 timestamping.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_TSEN;
|
|
|
+
|
|
|
+ //
|
|
|
+ // If necessary, initialize the timestamping system. This bit self-clears
|
|
|
+ // once the system time is loaded. Only do this if initialization is not
|
|
|
+ // currently ongoing.
|
|
|
+ //
|
|
|
+ if (!(HWREG(ui32Base + EMAC_O_TIMSTCTRL) & EMAC_TIMSTCTRL_TSINIT))
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_TSINIT;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Disables packet timestamping and stops the system clock.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to stop the system clock used to timestamp
|
|
|
+//! Ethernet frames and to disable timestamping.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampDisable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable IEEE 1588 timestamping.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) &= ~EMAC_TIMSTCTRL_TSEN;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the current system time.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Seconds is the seconds value of the new system clock setting.
|
|
|
+//! \param ui32SubSeconds is the subseconds value of the new system clock
|
|
|
+//! setting.
|
|
|
+//!
|
|
|
+//! This function may be used to set the current system time. The system
|
|
|
+//! clock is set to the value passed in the \e ui32Seconds and
|
|
|
+//! \e ui32SubSeconds parameters.
|
|
|
+//!
|
|
|
+//! The meaning of \e ui32SubSeconds depends on the current system time
|
|
|
+//! configuration. If EMACTimestampConfigSet() was previously called with
|
|
|
+//! the \e EMAC_TS_DIGITAL_ROLLOVER configuration option, each bit in the
|
|
|
+//! \e ui32SubSeconds value represents 1 ns. If \e EMAC_TS_BINARY_ROLLOVER was
|
|
|
+//! specified instead, a \e ui32SubSeconds bit represents 0.46 ns.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampSysTimeSet(uint32_t ui32Base, uint32_t ui32Seconds,
|
|
|
+ uint32_t ui32SubSeconds)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the new time to the system time update registers.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSECU) = ui32Seconds;
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMNANOU) = ui32SubSeconds;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous update to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_TIMSTCTRL) & EMAC_TIMSTCTRL_TSINIT)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Spin for a while.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Force the system clock to reset.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_TSINIT;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Gets the current system time.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pui32Seconds points to storage for the current seconds value.
|
|
|
+//! \param pui32SubSeconds points to storage for the current subseconds value.
|
|
|
+//!
|
|
|
+//! This function may be used to get the current system time.
|
|
|
+//!
|
|
|
+//! The meaning of \e ui32SubSeconds depends on the current system time
|
|
|
+//! configuration. If EMACTimestampConfigSet() was previously called with
|
|
|
+//! the \e EMAC_TS_DIGITAL_ROLLOVER configuration option, each bit in the
|
|
|
+//! \e ui32SubSeconds value represents 1 ns. If \e EMAC_TS_BINARY_ROLLOVER was
|
|
|
+//! specified instead, a \e ui32SubSeconds bit represents 0.46 ns.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampSysTimeGet(uint32_t ui32Base, uint32_t *pui32Seconds,
|
|
|
+ uint32_t *pui32SubSeconds)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pui32Seconds);
|
|
|
+ ASSERT(pui32SubSeconds);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the two-part system time from the seconds and nanoseconds
|
|
|
+ // registers. We do this in a way that should guard against us reading
|
|
|
+ // the registers across a nanosecond wrap.
|
|
|
+ //
|
|
|
+ do
|
|
|
+ {
|
|
|
+ *pui32Seconds = HWREG(ui32Base + EMAC_O_TIMSEC);
|
|
|
+ *pui32SubSeconds = HWREG(ui32Base + EMAC_O_TIMNANO);
|
|
|
+ }
|
|
|
+ while (*pui32Seconds != HWREG(ui32Base + EMAC_O_TIMNANO));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Adjusts the current system time upwards or downwards by a given amount.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Seconds is the seconds value of the time update to apply.
|
|
|
+//! \param ui32SubSeconds is the subseconds value of the time update to apply.
|
|
|
+//! \param bInc defines the direction of the update.
|
|
|
+//!
|
|
|
+//! This function may be used to adjust the current system time either upwards
|
|
|
+//! or downwards by a given amount. The size of the adjustment is given by
|
|
|
+//! the \e ui32Seconds and \e ui32SubSeconds parameter and the direction
|
|
|
+//! by the \e bInc parameter. When \e bInc is \e true, the system time is
|
|
|
+//! advanced by the interval given. When it is \e false, the time is retarded
|
|
|
+//! by the interval.
|
|
|
+//!
|
|
|
+//! The meaning of \e ui32SubSeconds depends on the current system time
|
|
|
+//! configuration. If EMACTimestampConfigSet() was previously called with
|
|
|
+//! the \e EMAC_TS_DIGITAL_ROLLOVER configuration option, each bit in the
|
|
|
+//! subsecond value represents 1 ns. If \e EMAC_TS_BINARY_ROLLOVER was
|
|
|
+//! specified instead, a subsecond bit represents 0.46 ns.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampSysTimeUpdate(uint32_t ui32Base, uint32_t ui32Seconds,
|
|
|
+ uint32_t ui32SubSeconds, bool bInc)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the new time to the system time update registers.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSECU) = ui32Seconds;
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMNANOU) = ui32SubSeconds |
|
|
|
+ (bInc ? 0 : EMAC_TIMNANOU_ADDSUB);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous update to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_TIMSTCTRL) & EMAC_TIMSTCTRL_TSUPDT)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Spin for a while.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Force the system clock to update by the value provided.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_TSUPDT;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Adjusts the system time update rate when using the fine correction method.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Increment is the number to add to the accumulator register on
|
|
|
+//! each tick of the 25-MHz main oscillator.
|
|
|
+//!
|
|
|
+//! This function is used to control the rate of update of the system time
|
|
|
+//! when in fine update mode. Fine correction mode is selected if
|
|
|
+//! \e EMAC_TS_UPDATE_FINE is supplied in the \e ui32Config parameter passed
|
|
|
+//! to a previous call to EMACTimestampConfigSet(). Fine update mode is
|
|
|
+//! typically used when synchronizing the local clock to the IEEE 1588 master
|
|
|
+//! clock. The subsecond counter is incremented by the number passed to
|
|
|
+//! EMACTimestampConfigSet() in the \e ui32SubSecondInc parameter each time a
|
|
|
+//! 32-bit accumulator register generates a carry. The accumulator register is
|
|
|
+//! incremented by the "addend" value on each main oscillator tick, and this
|
|
|
+//! addend value is modified to allow fine control over the rate of change of
|
|
|
+//! the timestamp counter. The addend value is calculated using the ratio of
|
|
|
+//! the main oscillator clock rate and the desired IEEE 1588 clock rate and the
|
|
|
+//! \e ui32SubSecondInc value is set to correspond to the desired IEEE 1588
|
|
|
+//! clock rate.
|
|
|
+//!
|
|
|
+//! As an example, using digital rollover mode and a 25-MHz main oscillator
|
|
|
+//! clock with a desired IEEE 1588 clock accuracy of 12.5 MHz, and having made
|
|
|
+//! a previous call to EMACTimestampConfigSet() with \e ui32SubSecondInc set to
|
|
|
+//! the 12.5-MHz clock period of 80 ns, the initial \e ui32Increment value
|
|
|
+//! would be set to 0x80000000 to generate a carry on every second main
|
|
|
+//! oscillator tick. Because the system time updates each time the accumulator
|
|
|
+//! overflows, small changes in the \e ui32Increment value can be used to very
|
|
|
+//! finely control the system time rate.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//!
|
|
|
+//! \sa EMACTimestampConfigSet()
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampAddendSet(uint32_t ui32Base, uint32_t ui32Increment)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMADD) = ui32Increment;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous update to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_TIMSTCTRL) & EMAC_TIMSTCTRL_ADDREGUP)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Spin for a while.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Force the system clock to update by the value provided.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_ADDREGUP;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the target system time at which the next Ethernet timer interrupt is
|
|
|
+//! generated.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Seconds is the second value of the desired target time.
|
|
|
+//! \param ui32SubSeconds is the subseconds value of the desired target time.
|
|
|
+//!
|
|
|
+//! This function may be used to schedule an interrupt at some future time.
|
|
|
+//! The time reference for the function is the IEEE 1588 time as returned by
|
|
|
+//! EMACTimestampSysTimeGet(). To generate an interrupt when the system
|
|
|
+//! time exceeds a given value, call this function to set the desired time,
|
|
|
+//! then EMACTimestampTargetIntEnable() to enable the interrupt. When the
|
|
|
+//! system time increments past the target time, an Ethernet interrupt with
|
|
|
+//! status \b EMAC_INT_TIMESTAMP is generated.
|
|
|
+//!
|
|
|
+//! The accuracy of the interrupt timing depends on the Ethernet timer
|
|
|
+//! update frequency and the subsecond increment value currently in use. The
|
|
|
+//! interrupt is generated on the first timer increment that causes the
|
|
|
+//! system time to be greater than or equal to the target time set.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampTargetSet(uint32_t ui32Base, uint32_t ui32Seconds,
|
|
|
+ uint32_t ui32SubSeconds)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous write to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_TARGNANO) & EMAC_TARGNANO_TRGTBUSY)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the new target time.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TARGSEC) = ui32Seconds;
|
|
|
+ HWREG(ui32Base + EMAC_O_TARGNANO) = ui32SubSeconds;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables the Ethernet system time interrupt.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be used after EMACTimestampTargetSet() to schedule an
|
|
|
+//! interrupt at some future time. The time reference for the function is
|
|
|
+//! the IEEE 1588 time as returned by EMACTimestampSysTimeGet(). To generate
|
|
|
+//! an interrupt when the system time exceeds a given value, call this function
|
|
|
+//! to set the desired time, then EMACTimestampTargetIntEnable() to enable the
|
|
|
+//! interrupt. When the system time increments past the target time, an
|
|
|
+//! Ethernet interrupt with status \b EMAC_INT_TIMESTAMP is generated.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampTargetIntEnable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the bit to enable the timestamp target interrupt. This bit clears
|
|
|
+ // automatically when the interrupt fires after which point, you must
|
|
|
+ // set a new target time and re-enable the interrupts.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) |= EMAC_TIMSTCTRL_INTTRIG;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Disables the Ethernet system time interrupt.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be used to disable any pending Ethernet system time
|
|
|
+//! interrupt previously scheduled using calls to EMACTimestampTargetSet()
|
|
|
+//! and EMACTimestampTargetIntEnable().
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampTargetIntDisable(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Clear the bit to disable the timestamp target interrupt. This bit
|
|
|
+ // clears automatically when the interrupt fires, so it only must be
|
|
|
+ // disabled if you want to cancel a previously-set interrupt.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_TIMSTCTRL) &= ~EMAC_TIMSTCTRL_INTTRIG;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Reads the status of the Ethernet system time interrupt.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! When an Ethernet interrupt occurs and \b EMAC_INT_TIMESTAMP is reported
|
|
|
+//! bu EMACIntStatus(), this function must be called to read and clear the
|
|
|
+//! timer interrupt status.
|
|
|
+//!
|
|
|
+//! \return The return value is the logical OR of the values
|
|
|
+//! \b EMAC_TS_INT_TS_SEC_OVERFLOW and \b EMAC_TS_INT_TARGET_REACHED.
|
|
|
+//!
|
|
|
+//! - \b EMAC_TS_INT_TS_SEC_OVERFLOW indicates that the second counter in the
|
|
|
+//! hardware timer has rolled over.
|
|
|
+//! - \b EMAC_TS_INT_TARGET_REACHED indicates that the system time incremented
|
|
|
+//! past the value set in an earlier call to EMACTimestampTargetSet(). When
|
|
|
+//! this occurs, a new target time may be set and the interrupt re-enabled
|
|
|
+//! using calls to EMACTimestampTargetSet() and
|
|
|
+//! EMACTimestampTargetIntEnable().
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACTimestampIntStatus(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the current interrupt status from the timestamp module.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_TIMSTAT));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Configures the Ethernet MAC PPS output in simple mode.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32FreqConfig determines the frequency of the output generated on
|
|
|
+//! the PPS pin.
|
|
|
+//!
|
|
|
+//! This function configures the Ethernet MAC PPS (Pulse Per Second) engine to
|
|
|
+//! operate in its simple mode which allows the generation of a few, fixed
|
|
|
+//! frequencies and pulse widths on the PPS pin. If more complex pulse
|
|
|
+//! train generation is required, the MAC also provides a command-based
|
|
|
+//! PPS control mode that can be selected by calling
|
|
|
+//! EMACTimestampPPSCommandModeSet().
|
|
|
+//!
|
|
|
+//! The \e ui32FreqConfig parameter may take one of the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PPS_SINGLE_PULSE generates a single high pulse on the PPS
|
|
|
+//! output once per second. The pulse width is the same as the system clock
|
|
|
+//! period.
|
|
|
+//! - \b EMAC_PPS_1HZ generates a 1Hz signal on the PPS output. This option
|
|
|
+//! is not available if the system time subsecond counter is currently
|
|
|
+//! configured to operate in binary rollover mode.
|
|
|
+//! - \b EMAC_PPS_2HZ, \b EMAC_PPS_4HZ, \b EMAC_PPS_8HZ,
|
|
|
+//! \b EMAC_PPS_16HZ, \b EMAC_PPS_32HZ, \b EMAC_PPS_64HZ,
|
|
|
+//! \b EMAC_PPS_128HZ, \b EMAC_PPS_256HZ, \b EMAC_PPS_512HZ,
|
|
|
+//! \b EMAC_PPS_1024HZ, \b EMAC_PPS_2048HZ, \b EMAC_PPS_4096HZ,
|
|
|
+//! \b EMAC_PPS_8192HZ, \b EMAC_PPS_16384HZ generate the requested
|
|
|
+//! frequency on the PPS output in both binary and digital rollover modes.
|
|
|
+//! - \b EMAC_PPS_32768HZ generates a 32KHz signal on the PPS output. This
|
|
|
+//! option is not available if the system time subsecond counter is currently
|
|
|
+//! configured to operate in digital rollover mode.
|
|
|
+//!
|
|
|
+//! Except when \b EMAC_PPS_SINGLE_PULSE is specified, the signal generated
|
|
|
+//! on PPS has a duty cycle of 50% when binary rollover mode is used for the
|
|
|
+//! system time subsecond count. In digital mode, the output frequency
|
|
|
+//! averages the value requested and is resynchronized each second. For
|
|
|
+//! example, if \b EMAC_PPS_4HZ is selected in digital rollover mode, the
|
|
|
+//! output generates three clocks with 50 percent duty cycle and 268 ms
|
|
|
+//! period followed by a fourth clock of 195 ms period, 134 ms low and 61 ms high.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampPPSSimpleModeSet(uint32_t ui32Base, uint32_t ui32FreqConfig)
|
|
|
+{
|
|
|
+ bool bDigital;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Are we currently running the clock in digital or binary rollover mode?
|
|
|
+ //
|
|
|
+ bDigital = (HWREG(ui32Base + EMAC_O_TIMSTCTRL) &
|
|
|
+ EMAC_TS_DIGITAL_ROLLOVER) ? true : false;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Weed out some unsupported frequencies. The hardware can't produce a
|
|
|
+ // 1Hz output when we are in binary rollover mode and can't produce a
|
|
|
+ // 32KHz output when we are digital rollover mode.
|
|
|
+ //
|
|
|
+ ASSERT(bDigital || (ui32FreqConfig != EMAC_PPS_1HZ));
|
|
|
+ ASSERT(!bDigital || (ui32FreqConfig != EMAC_PPS_32768HZ));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Adjust the supplied frequency if we are currently in binary update mode
|
|
|
+ // where the control value generates an output that is twice as fast as
|
|
|
+ // in digital mode.
|
|
|
+ //
|
|
|
+ if ((ui32FreqConfig != EMAC_PPS_SINGLE_PULSE) && !bDigital)
|
|
|
+ {
|
|
|
+ ui32FreqConfig--;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the frequency control value to the PPS control register, clearing
|
|
|
+ // the PPSEN0 bit to ensure that the PPS engine is in simple mode and not
|
|
|
+ // waiting for a command. We also clear the TRGMODS0 field to revert to
|
|
|
+ // the default operation of the target time registers.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PPSCTRL) = ui32FreqConfig;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Configures the Ethernet MAC PPS output in command mode.
|
|
|
+
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Config determines how the system target time is used.
|
|
|
+//!
|
|
|
+//! The simple mode of operation offered by the PPS (Pulse Per Second) engine
|
|
|
+//! may be too restrictive for some applications. The second mode, however,
|
|
|
+//! allows complex pulse trains to be generated using commands that tell the
|
|
|
+//! engine to send individual pulses or start and stop trains if pulses. In
|
|
|
+//! this mode, the pulse width and period may be set arbitrarily based on
|
|
|
+//! ticks of the clock used to update the system time. Commands are triggered
|
|
|
+//! at specific times using the target time last set using a call to
|
|
|
+//! EMACTimestampTargetSet().
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter may be used to control whether the target
|
|
|
+//! time is used to trigger commands only or can also generate an interrupt
|
|
|
+//! to the CPU. Valid values are:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PPS_TARGET_INT configures the target time to only raise
|
|
|
+//! an interrupt and not to trigger any pending PPS command.
|
|
|
+//! - \b EMAC_PPS_TARGET_PPS configures the target time to trigger a pending
|
|
|
+//! PPS command but not raise an interrupt.
|
|
|
+//! - \b EMAC_PPS_TARGET_BOTH configures the target time to trigger any
|
|
|
+//! pending PPS command and also raise an interrupt.
|
|
|
+//!
|
|
|
+//! To use command mode, an application must call this function to enable the
|
|
|
+//! mode, then call:
|
|
|
+//!
|
|
|
+//! - EMACTimestampPPSPeriodSet() to set the desired pulse width and period
|
|
|
+//! then
|
|
|
+//! - EMACTimestampTargetSet() to set the time at which the next command is
|
|
|
+//! executed, and finally
|
|
|
+//! - EMACTimestampPPSCommand() to send a command to cause the pulse or
|
|
|
+//! pulse train to be started at the required time.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampPPSCommandModeSet(uint32_t ui32Base, uint32_t ui32Config)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(!(ui32Config & (EMAC_PPS_TARGET_INT | EMAC_PPS_TARGET_PPS |
|
|
|
+ EMAC_PPS_TARGET_BOTH)));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous command write to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_PPSCTRL) & EMAC_PPSCTRL_PPSCTRL_M)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Wait a bit.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the configuration value to the PPS control register, setting the
|
|
|
+ // PPSEN0 bit to ensure that the PPS engine is in command mode and
|
|
|
+ // clearing the command in the PPSCTRL field.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PPSCTRL) = (EMAC_PPSCTRL_PPSEN0 | ui32Config);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sends a command to control the PPS output from the Ethernet MAC.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8Cmd identifies the command to be sent.
|
|
|
+//!
|
|
|
+//! This function may be used to send a command to the MAC PPS (Pulse Per
|
|
|
+//! Second) controller when it is operating in command mode. Command mode
|
|
|
+//! is selected by calling EMACTimestampPPSCommandModeSet(). Valid
|
|
|
+//! commands are as follow:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PPS_COMMAND_NONE indicates no command.
|
|
|
+//! - \b EMAC_PPS_COMMAND_START_SINGLE indicates that a single high pulse
|
|
|
+//! should be generated when the system time reaches the current target time.
|
|
|
+//! - \b EMAC_PPS_COMMAND_START_TRAIN indicates that a train of pulses
|
|
|
+//! should be started when the system time reaches the current target time.
|
|
|
+//! - \b EMAC_PPS_COMMAND_CANCEL_START cancels any pending start command if
|
|
|
+//! the system time has not yet reached the programmed target time.
|
|
|
+//! - \b EMAC_PPS_COMMAND_STOP_AT_TIME indicates that the current pulse
|
|
|
+//! train should be stopped when the system time reaches the current target
|
|
|
+//! time.
|
|
|
+//! - \b EMAC_PPS_COMMAND_STOP_NOW indicates that the current pulse train
|
|
|
+//! should be stopped immediately.
|
|
|
+//! - \b EMAC_PPS_COMMAND_CANCEL_STOP cancels any pending stop command if
|
|
|
+//! the system time has not yet reached the programmed target time.
|
|
|
+//!
|
|
|
+//! In all cases, the width of the pulses generated is governed by the
|
|
|
+//! \e ui32Width parameter passed to EMACTimestampPPSPeriodSet(). If a
|
|
|
+//! command starts a train of pulses, the period of the pulses is governed
|
|
|
+//! by the \e ui32Period parameter passed to the same function.
|
|
|
+//! Target times associated with PPS commands are set by calling
|
|
|
+//! EMACTimestampTargetSet().
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampPPSCommand(uint32_t ui32Base, uint8_t ui8Cmd)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Wait for any previous command write to complete.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_PPSCTRL) & EMAC_PPSCTRL_PPSCTRL_M)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Wait a bit.
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the command to the PPS control register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PPSCTRL) = (EMAC_PPSCTRL_PPSEN0 | ui8Cmd);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the period and width of the pulses on the Ethernet MAC PPS output.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Period is the period of the PPS output expressed in terms of
|
|
|
+//! system time update ticks.
|
|
|
+//! \param ui32Width is the width of the high portion of the PPS output
|
|
|
+//! expressed in terms of system time update ticks.
|
|
|
+//!
|
|
|
+//! This function may be used to control the period and duty cycle of the
|
|
|
+//! signal output on the Ethernet MAC PPS pin when the PPS generator is
|
|
|
+//! operating in command mode and a command to send one or more pulses has been
|
|
|
+//! executed. Command mode is selected by calling
|
|
|
+//! EMACTimestampPPSCommandModeSet().
|
|
|
+//!
|
|
|
+//! In simple mode, the PPS output signal frequency is controlled by the
|
|
|
+//! \e ui32FreqConfig parameter passed to EMACTimestampPPSSimpleModeSet().
|
|
|
+//!
|
|
|
+//! The \e ui32Period and \e ui32Width parameters are expressed in terms of
|
|
|
+//! system time update ticks. When the system time is operating in coarse
|
|
|
+//! update mode, each tick is equivalent to the system clock. In fine update
|
|
|
+//! mode, a tick occurs every time the 32-bit system time accumulator overflows
|
|
|
+//! and this, in turn, is determined by the value passed to the function
|
|
|
+//! EMACTimestampAddendSet(). Regardless of the tick source, each tick
|
|
|
+//! increments the actual system time, queried using EMACTimestampSysTimeGet()
|
|
|
+//! by the subsecond increment value passed in the \e ui32SubSecondInc to
|
|
|
+//! EMACTimestampConfigSet().
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACTimestampPPSPeriodSet(uint32_t ui32Base, uint32_t ui32Period,
|
|
|
+ uint32_t ui32Width)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the desired PPS period and pulse width.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PPS0INTVL) = ui32Period;
|
|
|
+ HWREG(ui32Base + EMAC_O_PPS0WIDTH) = ui32Width;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets options related to reception of VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui16Tag is the IEEE 802.1Q VLAN tag expected for incoming frames.
|
|
|
+//! \param ui32Config determines how the receiver handles VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! This function configures the receiver's handling of IEEE 802.1Q VLAN
|
|
|
+//! tagged frames. Incoming tagged frames are filtered using either a perfect
|
|
|
+//! filter or a hash filter. When hash filtering is disabled, VLAN frames
|
|
|
+//! tagged with the value of \e ui16Tag pass the filter and all others are
|
|
|
+//! rejected. The tag comparison may involve all 16 bits or only the 12-bit
|
|
|
+//! VLAN ID portion of the tag.
|
|
|
+//!
|
|
|
+//! The \e ui32Config parameter is a logical OR of the following values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_RX_HASH_ENABLE enables hash filtering for VLAN tags. If
|
|
|
+//! this flag is absent, perfect filtering using the tag supplied in \e ui16Tag
|
|
|
+//! is performed. The hash filter may be set using EMACVLANHashFilterSet(),
|
|
|
+//! and EMACVLANHashFilterBitCalculate() may be used to determine which bits
|
|
|
+//! to set in the filter for given VLAN tags.
|
|
|
+//! - \b EMAC_VLAN_RX_SVLAN_ENABLE causes the receiver to recognize S-VLAN
|
|
|
+//! (Type = 0x88A8) frames as valid VLAN-tagged frames. If absent, only
|
|
|
+//! frames with type 0x8100 are considered valid VLAN frames.
|
|
|
+//! - \b EMAC_VLAN_RX_INVERSE_MATCH causes the receiver to pass all VLAN
|
|
|
+//! frames for which the tags do not match the supplied \e ui16Tag value. If
|
|
|
+//! this flag is absent, only tagged frames matching \e ui16Tag are passed.
|
|
|
+//! - \b EMAC_VLAN_RX_12BIT_TAG causes the receiver to compare only the
|
|
|
+//! bottom 12 bits of \e ui16Tag when performing either perfect or hash
|
|
|
+//! filtering of VLAN frames. If this flag is absent, all 16 bits of the frame
|
|
|
+//! tag are examined when filtering. If this flag is set and \e ui16Tag has
|
|
|
+//! all bottom 12 bits clear, the receiver passes all frames with types
|
|
|
+//! 0x8100 or 0x88A8 regardless of the tag values they contain.
|
|
|
+//!
|
|
|
+//! \note To ensure that VLAN frames that fail the tag filter are dropped
|
|
|
+//! by the MAC, EMACFrameFilterSet() must be called with the \b
|
|
|
+//! EMAC_FRMFILTER_VLAN flag set in the \e ui32FilterOpts parameter. If
|
|
|
+//! this flag is not set, failing VLAN packets are received by the
|
|
|
+//! application, but bit 10 of RDES0 (\b EMAC_FRMFILTER_VLAN) is clear
|
|
|
+//! indicating that the packet did not match the current VLAG tag filter.
|
|
|
+//!
|
|
|
+//! \sa EMACVLANRxConfigGet()
|
|
|
+//!
|
|
|
+//! \return None
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACVLANRxConfigSet(uint32_t ui32Base, uint16_t ui16Tag, uint32_t ui32Config)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the VLAN tag register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_VLANTG) =
|
|
|
+ ui32Config | (((uint32_t)ui16Tag) << EMAC_VLANTG_VL_S);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the currently-set options related to reception of VLAN-tagged
|
|
|
+//! frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pui16Tag points to storage which is written with the currently
|
|
|
+//! configured VLAN tag used for perfect filtering.
|
|
|
+//!
|
|
|
+//! This function returns information on how the receiver is currently
|
|
|
+//! handling IEEE 802.1Q VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! \sa EMACVLANRxConfigSet()
|
|
|
+//!
|
|
|
+//! \return Returns flags defining how VLAN-tagged frames are handled. The
|
|
|
+//! value is a logical OR of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_RX_HASH_ENABLE indicates that hash filtering is enabled
|
|
|
+//! for VLAN tags. If this flag is absent, perfect filtering using the tag
|
|
|
+//! returned in \e *pui16Tag is performed.
|
|
|
+//! - \b EMAC_VLAN_RX_SVLAN_ENABLE indicates that the receiver recognizes
|
|
|
+//! S-VLAN (Type = 0x88A8) frames as valid VLAN-tagged frames. If absent, only
|
|
|
+//! frames with type 0x8100 are considered valid VLAN frames.
|
|
|
+//! - \b EMAC_VLAN_RX_INVERSE_MATCH indicates that the receiver passes all
|
|
|
+//! VLAN frames for which the tags do not match the \e *pui16Tag value. If
|
|
|
+//! this flag is absent, only tagged frames matching \e *pui16Tag are passed.
|
|
|
+//! - \b EMAC_VLAN_RX_12BIT_TAG indicates that the receiver is comparing only
|
|
|
+//! the bottom 12 bits of \e *pui16Tag when performing either perfect or hash
|
|
|
+//! filtering of VLAN frames. If this flag is absent, all 16 bits of the frame
|
|
|
+//! tag are examined when filtering. If this flag is set and \e *pui16Tag has
|
|
|
+//! all bottom 12 bits clear, the receiver passes all frames with types
|
|
|
+//! 0x8100 or 0x88A8 regardless of the tag values they contain.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACVLANRxConfigGet(uint32_t ui32Base, uint16_t *pui16Tag)
|
|
|
+{
|
|
|
+ uint32_t ui32Value;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pui16Tag);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the VLAN tag register.
|
|
|
+ //
|
|
|
+ ui32Value = HWREG(ui32Base + EMAC_O_VLANTG);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Extract the VLAN tag from the register.
|
|
|
+ //
|
|
|
+ *pui16Tag = (ui32Value & EMAC_VLANTG_VL_M) >> EMAC_VLANTG_VL_S;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the configuration flags.
|
|
|
+ //
|
|
|
+ return (ui32Value & ~EMAC_VLANTG_VL_M);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets options related to transmission of VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui16Tag is the VLAN tag to be used when inserting or replacing tags
|
|
|
+//! in transmitted frames.
|
|
|
+//! \param ui32Config determines the VLAN-related processing performed by
|
|
|
+//! the transmitter.
|
|
|
+//!
|
|
|
+//! This function is used to configure transmitter options relating to
|
|
|
+//! IEEE 802.1Q VLAN tagging. The transmitter may be set to insert tagging
|
|
|
+//! into untagged frames or replace existing tags with new values.
|
|
|
+//!
|
|
|
+//! The \e ui16Tag parameter contains the VLAN tag to be used in outgoing
|
|
|
+//! tagged frames. The \e ui32Config parameter is a logical OR of the
|
|
|
+//! following labels:
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_TX_SVLAN uses the S-VLAN type (0x88A8) when inserting or
|
|
|
+//! replacing tags in transmitted frames. If this label is absent, C-VLAN
|
|
|
+//! type (0x8100) is used.
|
|
|
+//! - \b EMAC_VLAN_TX_USE_VLC informs the transmitter that the VLAN tag
|
|
|
+//! handling should be defined by the VLAN control (VLC) value provided in
|
|
|
+//! this function call. If this tag is absent, VLAN handling is controlled
|
|
|
+//! by fields in the transmit descriptor.
|
|
|
+//!
|
|
|
+//! If \b EMAC_VLAN_TX_USE_VLC is set, one of the following four labels
|
|
|
+//! must also be included to define the transmit VLAN tag handling:
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_NONE instructs the transmitter to perform no VLAN
|
|
|
+//! tag insertion, deletion or replacement.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_DELETE instructs the transmitter to remove VLAN
|
|
|
+//! tags from all transmitted frames that contain them. As a result, bytes
|
|
|
+//! 13, 14, 15 and 16 are removed from all frames with types 0x8100 or 0x88A8.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_INSERT instructs the transmitter to insert a VLAN
|
|
|
+//! type and tag into all outgoing frames regardless of whether or not they
|
|
|
+//! already contain a VLAN tag.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_REPLACE instructs the transmitter to replace the
|
|
|
+//! VLAN tag in all frames of type 0x8100 or 0x88A8 with the value provided to
|
|
|
+//! this function in the \e ui16Tag parameter.
|
|
|
+//!
|
|
|
+//! \return None
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACVLANTxConfigSet(uint32_t ui32Base, uint16_t ui16Tag, uint32_t ui32Config)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the VLAN Tag Inclusion or Replacement register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_VLNINCREP) =
|
|
|
+ ui32Config | ((uint32_t)ui16Tag << EMAC_VLNINCREP_VLT_S);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns currently-selected options related to transmission of VLAN-tagged
|
|
|
+//! frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pui16Tag points to storage that is written with the VLAN tag
|
|
|
+//! currently being used for insertion or replacement.
|
|
|
+//!
|
|
|
+//! This function returns information on the current settings related to VLAN
|
|
|
+//! tagging of transmitted frames.
|
|
|
+//!
|
|
|
+//! \sa EMACVLANTxConfigSet()
|
|
|
+//!
|
|
|
+//! \return Returns flags describing the current VLAN configuration relating
|
|
|
+//! to frame transmission. The return value is a logical OR of the following
|
|
|
+//! values:
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_TX_SVLAN indicates that the S-VLAN type (0x88A8) is
|
|
|
+//! being used when inserting or replacing tags in transmitted frames. If
|
|
|
+//! this label is absent, C-VLAN type (0x8100) is being used.
|
|
|
+//! - \b EMAC_VLAN_TX_USE_VLC indicates that the transmitter is processing
|
|
|
+//! VLAN frames according to the VLAN control (VLC) value returned here. If
|
|
|
+//! this tag is absent, VLAN handling is controlled by fields in the transmit
|
|
|
+//! descriptor.
|
|
|
+//!
|
|
|
+//! If \b EMAC_VLAN_TX_USE_VLC is returned, one of the following four labels
|
|
|
+//! is also included to define the transmit VLAN tag handling. Note that this
|
|
|
+//! value may be extracted from the return value using the mask \b
|
|
|
+//! EMAC_VLAN_TX_VLC_MASK.
|
|
|
+//!
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_NONE indicates that the transmitter is not
|
|
|
+//! performing VLAN tag insertion, deletion or replacement.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_DELETE indicates that the transmitter is removing
|
|
|
+//! VLAN tags from all transmitted frames which contain them.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_INSERT indicates that the transmitter is inserting
|
|
|
+//! a VLAN type and tag into all outgoing frames regardless of whether or not
|
|
|
+//! they already contain a VLAN tag.
|
|
|
+//! - \b EMAC_VLAN_TX_VLC_REPLACE indicates that the transmitter is replacing
|
|
|
+//! the VLAN tag in all transmitted frames of type 0x8100 or 0x88A8 with the
|
|
|
+//! value returned in \e *pui16Tag.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACVLANTxConfigGet(uint32_t ui32Base, uint16_t *pui16Tag)
|
|
|
+{
|
|
|
+ uint32_t ui32Value;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pui16Tag);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the VLAN Tag Inclusion or Replacement register.
|
|
|
+ //
|
|
|
+ ui32Value = HWREG(ui32Base + EMAC_O_VLNINCREP);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Extract the tag.
|
|
|
+ //
|
|
|
+ *pui16Tag = (uint16_t)((ui32Value & EMAC_VLNINCREP_VLT_M) >>
|
|
|
+ EMAC_VLNINCREP_VLT_S);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the configuration flags.
|
|
|
+ //
|
|
|
+ return (ui32Value & ~EMAC_VLNINCREP_VLT_M);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the bit number to set in the VLAN hash filter corresponding to a
|
|
|
+//! given tag.
|
|
|
+//!
|
|
|
+//! \param ui16Tag is the VLAN tag for which the hash filter bit number is to
|
|
|
+//! be determined.
|
|
|
+//!
|
|
|
+//! This function may be used to determine which bit in the VLAN hash filter
|
|
|
+//! to set to describe a given 12- or 16-bit VLAN tag. The returned value is
|
|
|
+//! a 4-bit value indicating the bit number to set within the 16-bit VLAN
|
|
|
+//! hash filter. For example, if 0x02 is returned, this indicates that bit
|
|
|
+//! 2 of the hash filter must be set to pass the supplied VLAN tag.
|
|
|
+//!
|
|
|
+//! \return Returns the bit number to set in the VLAN hash filter to describe
|
|
|
+//! the passed tag.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACVLANHashFilterBitCalculate(uint16_t ui16Tag)
|
|
|
+{
|
|
|
+ uint32_t ui32CRC, ui32Mask, ui32Loop;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Calculate the CRC for the MAC address.
|
|
|
+ //
|
|
|
+ ui32CRC = Crc32(0xFFFFFFFF, (uint8_t *)&ui16Tag, 2);
|
|
|
+ ui32CRC ^= 0xFFFFFFFF;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Determine the hash bit to use from the calculated CRC. This is the
|
|
|
+ // top 4 bits of the reversed CRC (or the bottom 4 bits of the calculated
|
|
|
+ // CRC with the bit order of those 4 bits reversed).
|
|
|
+ //
|
|
|
+ ui32Mask = 0;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Reverse the order of the bottom 4 bits of the calculated CRC.
|
|
|
+ //
|
|
|
+ for (ui32Loop = 0; ui32Loop < 4; ui32Loop++)
|
|
|
+ {
|
|
|
+ ui32Mask <<= 1;
|
|
|
+ ui32Mask |= (ui32CRC & 1);
|
|
|
+ ui32CRC >>= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the final hash filter bit index.
|
|
|
+ //
|
|
|
+ return (ui32Mask);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the hash filter used to control reception of VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Hash is the hash filter value to set.
|
|
|
+//!
|
|
|
+//! This function allows the VLAG tag hash filter to be set. By using hash
|
|
|
+//! filtering, several different VLAN tags can be filtered very easily at the
|
|
|
+//! cost of some false positive results that must be removed by software.
|
|
|
+//!
|
|
|
+//! The hash filter value passed in \e ui32Hash may be built up by calling
|
|
|
+//! EMACVLANHashFilterBitCalculate() for each VLAN tag that is to pass the
|
|
|
+//! filter and then set each of the bits for which the numbers are returned by
|
|
|
+//! that function. Care must be taken when clearing bits in the hash filter
|
|
|
+//! due to the fact that there is a many-to-one correspondence between VLAN
|
|
|
+//! tags and hash filter bits.
|
|
|
+//!
|
|
|
+//! \return None
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACVLANHashFilterSet(uint32_t ui32Base, uint32_t ui32Hash)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the VLAN Hash Table register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_VLANHASH) = ui32Hash;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current value of the hash filter used to control reception of
|
|
|
+//! VLAN-tagged frames.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function allows the current VLAN tag hash filter value to be returned.
|
|
|
+//! Additional VLAN tags may be added to this filter by setting the appropriate
|
|
|
+//! bits, determined by calling EMACVLANHashFilterBitCalculate(), and then
|
|
|
+//! calling EMACVLANHashFilterSet() to set the new filter value.
|
|
|
+//!
|
|
|
+//! \return Returns the current value of the VLAN hash filter.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACVLANHashFilterGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Return the VLAN Hash Table register.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_VLANHASH));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets values defining up to four frames used to trigger a remote wake-up.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pFilter points to the structure containing remote wake-up frame
|
|
|
+//! filter information.
|
|
|
+//!
|
|
|
+//! This function may be used to define up to four different frames that
|
|
|
+//! are considered by the Ethernet MAC to be remote wake-up signals. The
|
|
|
+//! data passed to the function describes a wake-up frame in terms of a CRC
|
|
|
+//! calculated on up to 31 payload bytes in the frame. The actual bytes used
|
|
|
+//! in the CRC calculation are defined by means of a bit mask where a ``1''
|
|
|
+//! indicates that a byte in the frame should contribute to the CRC
|
|
|
+//! calculation and a ``0'' indicates that the byte should be skipped, as well
|
|
|
+//! as an offset from the start of the frame to the payload byte that represents
|
|
|
+//! the first byte in the 31-byte CRC-checked sequence.
|
|
|
+//!
|
|
|
+//! The \e pFilter parameter points to a structure containing the information
|
|
|
+//! necessary to set up the filters. This structure contains the following
|
|
|
+//! fields, each of which is replicated 4 times, once for each possible wake-up
|
|
|
+//! frame:
|
|
|
+//!
|
|
|
+//! - \b pui32ByteMask defines whether a given byte in the chosen 31-byte
|
|
|
+//! sequence within the frame should contribute to the CRC calculation or not.
|
|
|
+//! A 1 indicates that the byte should contribute to the calculation, a 0
|
|
|
+//! causes the byte to be skipped.
|
|
|
+//! - \b pui8Command contains flags defining whether this filter is enabled
|
|
|
+//! and, if so, whether it refers to unicast or multicast packets. Valid
|
|
|
+//! values are one of \b EMAC_RWU_FILTER_MULTICAST or \b
|
|
|
+//! EMAC_RWU_FILTER_UNICAST ORed with one of \b EMAC_RWU_FILTER_ENABLE or
|
|
|
+//! \b EMAC_RWU_FILTER_DISABLE.
|
|
|
+//! - \b pui8Offset defines the zero-based index of the byte within the frame
|
|
|
+//! at which CRC checking defined by \b pui32ByteMask begins.
|
|
|
+//! Alternatively, this value can be thought of as the number of bytes in the
|
|
|
+//! frame that the MAC skips before accumulating the CRC based on the pattern
|
|
|
+//! in \b pui32ByteMask.
|
|
|
+//! - \b pui16CRC provides the value of the calculated CRC for a valid remote
|
|
|
+//! wake-up frame. If the incoming frame is processed according to the filter
|
|
|
+//! values provided and the final CRC calculation equals this value, the
|
|
|
+//! frame is considered to be a valid remote wake-up frame.
|
|
|
+//!
|
|
|
+//! Note that this filter uses CRC16 rather than CRC32 as used in frame
|
|
|
+//! checksums. The required CRC uses a direct algorithm with polynomial 0x8005,
|
|
|
+//! initial seed value 0xFFFF, no final XOR and reversed data order. CRCs
|
|
|
+//! for use in this function may be determined using the online calculator
|
|
|
+//! found at http://www.zorc.breitbandkatze.de/crc.html.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRemoteWakeUpFrameFilterSet(uint32_t ui32Base,
|
|
|
+ const tEMACWakeUpFrameFilter *pFilter)
|
|
|
+{
|
|
|
+ uint32_t *pui32Data;
|
|
|
+ uint32_t ui32Loop;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pFilter);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Make sure that the internal register counter for the frame filter
|
|
|
+ // is reset. This bit automatically resets after 1 clock cycle.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PMTCTLSTAT) |= EMAC_PMTCTLSTAT_WUPFRRST;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get a word pointer to the supplied structure.
|
|
|
+ //
|
|
|
+ pui32Data = (uint32_t *)pFilter;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the 8 words of the wake-up filter definition to the hardware.
|
|
|
+ //
|
|
|
+ for (ui32Loop = 0; ui32Loop < 8; ui32Loop++)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Write a word of the filter definition.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_RWUFF) = pui32Data[ui32Loop];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the current remote wake-up frame filter configuration.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param pFilter points to the structure that is written with the current
|
|
|
+//! remote wake-up frame filter information.
|
|
|
+//!
|
|
|
+//! This function may be used to read the current wake-up frame filter
|
|
|
+//! settings. The data returned by the function describes wake-up frames in
|
|
|
+//! terms of a CRC calculated on up to 31 payload bytes in the frame. The
|
|
|
+//! actual bytes used in the CRC calculation are defined by means of a bit mask
|
|
|
+//! where a ``1'' indicates that a byte in the frame should contribute to the
|
|
|
+//! CRC calculation and a ``0'' indicates that the byte should be skipped, and
|
|
|
+//! an offset from the start of the frame to the payload byte that represents
|
|
|
+//! the first byte in the 31-byte CRC-checked sequence.
|
|
|
+//!
|
|
|
+//! The \e pFilter parameter points to storage that is written with a
|
|
|
+//! structure containing the information defining the frame filters. This
|
|
|
+//! structure contains the following fields, each of which is replicated 4
|
|
|
+//! times, once for each possible wake-up frame:
|
|
|
+//!
|
|
|
+//! - \b pui32ByteMask defines whether a given byte in the chosen 31-byte
|
|
|
+//! sequence within the frame should contribute to the CRC calculation or not.
|
|
|
+//! A 1 indicates that the byte should contribute to the calculation, a 0
|
|
|
+//! causes the byte to be skipped.
|
|
|
+//! - \b pui8Command contains flags defining whether this filter is enabled
|
|
|
+//! and, if so, whether it refers to unicast or multicast packets. Valid
|
|
|
+//! values are one of \b EMAC_RWU_FILTER_MULTICAST or \b
|
|
|
+//! EMAC_RWU_FILTER_UNICAST ORed with one of \b EMAC_RWU_FILTER_ENABLE or
|
|
|
+//! \b EMAC_RWU_FILTER_DISABLE.
|
|
|
+//! - \b pui8Offset defines the zero-based index of the byte within the frame
|
|
|
+//! at which CRC checking defined by \b pui32ByteMask begins.
|
|
|
+//! Alternatively, this value can be thought of as the number of bytes in the
|
|
|
+//! frame that the MAC skips before accumulating the CRC based on the pattern
|
|
|
+//! in \b pui32ByteMask.
|
|
|
+//! - \b pui16CRC provides the value of the calculated CRC for a valid remote
|
|
|
+//! wake-up frame. If the incoming frame is processed according to the filter
|
|
|
+//! values provided and the final CRC calculation equals this value, the
|
|
|
+//! frame is considered to be a valid remote wake-up frame.
|
|
|
+//!
|
|
|
+//! Note that this filter uses CRC16 rather than CRC32 as used in frame
|
|
|
+//! checksums.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACRemoteWakeUpFrameFilterGet(uint32_t ui32Base,
|
|
|
+ tEMACWakeUpFrameFilter *pFilter)
|
|
|
+{
|
|
|
+ uint32_t *pui32Data;
|
|
|
+ uint32_t ui32Loop;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(pFilter);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Make sure that the internal register counter for the frame filter
|
|
|
+ // is reset. This bit automatically resets after 1 clock cycle.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_PMTCTLSTAT) |= EMAC_PMTCTLSTAT_WUPFRRST;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Get a word pointer to the supplied structure.
|
|
|
+ //
|
|
|
+ pui32Data = (uint32_t *)pFilter;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the 8 words of the wake-up filter definition from the hardware.
|
|
|
+ //
|
|
|
+ for (ui32Loop = 0; ui32Loop < 8; ui32Loop++)
|
|
|
+ {
|
|
|
+ //
|
|
|
+ // Read a word of the filter definition.
|
|
|
+ //
|
|
|
+ pui32Data[ui32Loop] = HWREG(ui32Base + EMAC_O_RWUFF);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the Ethernet MAC remote wake-up configuration.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui32Flags defines which types of frame should trigger a remote
|
|
|
+//! wake-up and allows the MAC to be put into power-down mode.
|
|
|
+//!
|
|
|
+//! This function allows the MAC's remote wake-up features to be configured,
|
|
|
+//! determining which types of frame should trigger a wake-up event and
|
|
|
+//! allowing an application to place the MAC in power-down mode. In this
|
|
|
+//! mode, the MAC ignores all received frames until one matching a
|
|
|
+//! configured remote wake-up frame is received, at which point the MAC
|
|
|
+//! automatically exits power-down mode and continues to receive frames.
|
|
|
+//!
|
|
|
+//! The \e ui32Flags parameter is a logical OR of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PMT_GLOBAL_UNICAST_ENABLE instructs the MAC to wake up when any
|
|
|
+//! unicast frame matching the MAC destination address filter is received.
|
|
|
+//! - \b EMAC_PMT_WAKEUP_PACKET_ENABLE instructs the MAC to wake up when any
|
|
|
+//! received frame matches the remote wake-up filter configured via a call
|
|
|
+//! to EMACRemoteWakeUpFrameFilterSet().
|
|
|
+//! - \b EMAC_PMT_MAGIC_PACKET_ENABLE instructs the MAC to wake up when a
|
|
|
+//! standard Wake-on-LAN "magic packet" is received. The magic packet contains
|
|
|
+//! 6 bytes of 0xFF followed immediately by 16 repetitions of the destination
|
|
|
+//! MAC address.
|
|
|
+//! - \b EMAC_PMT_POWER_DOWN instructs the MAC to enter power-down mode and
|
|
|
+//! wait for an incoming frame matching the remote wake-up frames as described
|
|
|
+//! by other flags and via the remote wake-up filter. This flag should only
|
|
|
+//! set set if at least one other flag is specified to configure a wake-up
|
|
|
+//! frame type.
|
|
|
+//!
|
|
|
+//! When the MAC is in power-down mode, software may exit the mode by calling
|
|
|
+//! this function with the \b EMAC_PMT_POWER_DOWN flag absent from \e ui32Flags.
|
|
|
+//! If a configured wake-up frame is received while in power-down mode, the
|
|
|
+//! \b EMAC_INT_POWER_MGMNT interrupt is signaled and may be cleared by reading
|
|
|
+//! the status using EMACPowerManagementStatusGet().
|
|
|
+//!
|
|
|
+//! \note While it is possible to gate the clock to the MAC while it is in
|
|
|
+//! power-down mode, doing so prevents the reading of the registers required
|
|
|
+//! to determine the interrupt status and also prevents power-down mode from
|
|
|
+//! exiting via another call to this function.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPowerManagementControlSet(uint32_t ui32Base, uint32_t ui32Flags)
|
|
|
+{
|
|
|
+ uint32_t ui32Value;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+ ASSERT(~(ui32Flags & ~(EMAC_PMT_GLOBAL_UNICAST_ENABLE |
|
|
|
+ EMAC_PMT_WAKEUP_PACKET_ENABLE |
|
|
|
+ EMAC_PMT_MAGIC_PACKET_ENABLE |
|
|
|
+ EMAC_PMT_POWER_DOWN)));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the control/status register, clear all the bits we can set, mask
|
|
|
+ // in the new values then rewrite the new register value.
|
|
|
+ //
|
|
|
+ ui32Value = HWREG(ui32Base + EMAC_O_PMTCTLSTAT);
|
|
|
+ ui32Value &= ~(EMAC_PMTCTLSTAT_GLBLUCAST | EMAC_PMTCTLSTAT_WUPFREN |
|
|
|
+ EMAC_PMTCTLSTAT_MGKPKTEN | EMAC_PMTCTLSTAT_PWRDWN);
|
|
|
+ ui32Value |= ui32Flags;
|
|
|
+ HWREG(ui32Base + EMAC_O_PMTCTLSTAT) = ui32Value;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Queries the current Ethernet MAC remote wake-up configuration.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function allows the MAC's remote wake-up settings to be queried.
|
|
|
+//! These settings determine which types of frame should trigger a remote
|
|
|
+//! wake-up event
|
|
|
+//!
|
|
|
+//! \return Returns a logical OR of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PMT_GLOBAL_UNICAST_ENABLE indicates that the MAC wakes up when
|
|
|
+//! any unicast frame matching the MAC destination address filter is received.
|
|
|
+//! - \b EMAC_PMT_WAKEUP_PACKET_ENABLE indicates that the MAC wakes up when any
|
|
|
+//! received frame matches the remote wake-up filter configured via a call
|
|
|
+//! to EMACRemoteWakeUpFrameFilterSet().
|
|
|
+//! - \b EMAC_PMT_MAGIC_PACKET_ENABLE indicates that the MAC wakes up when a
|
|
|
+//! standard Wake-on-LAN "magic packet" is received. The magic packet contains
|
|
|
+//! 6 bytes of 0xFF followed immediately by 16 repetitions of the destination
|
|
|
+//! MAC address.
|
|
|
+//! - \b EMAC_PMT_POWER_DOWN indicates that the MAC is currently in power-down
|
|
|
+//! mode and is waiting for an incoming frame matching the remote wake-up
|
|
|
+//! frames as described by other returned flags and via the remote wake-up
|
|
|
+//! filter.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACPowerManagementControlGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the control/status register and mask off the control bits to return
|
|
|
+ // them to the caller.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_PMTCTLSTAT) &
|
|
|
+ (EMAC_PMTCTLSTAT_GLBLUCAST | EMAC_PMTCTLSTAT_WUPFREN |
|
|
|
+ EMAC_PMTCTLSTAT_MGKPKTEN | EMAC_PMTCTLSTAT_PWRDWN));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Queries the current Ethernet MAC remote wake-up status.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function returns information on the remote wake-up state of the
|
|
|
+//! Ethernet MAC. If the MAC has been woken up since the last call, the
|
|
|
+//! returned value indicates the type of received frame that caused the MAC
|
|
|
+//! to exit power-down state.
|
|
|
+//!
|
|
|
+//! \return Returns a logical OR of the following flags:
|
|
|
+//!
|
|
|
+//! - \b EMAC_PMT_POWER_DOWN indicates that the MAC is currently in power-down
|
|
|
+//! mode.
|
|
|
+//! - \b EMAC_PMT_WAKEUP_PACKET_RECEIVED indicates that the MAC exited
|
|
|
+//! power-down mode due to a remote wake-up frame being received. This
|
|
|
+//! function call clears this flag.
|
|
|
+//! - \b EMAC_PMT_MAGIC_PACKET_RECEIVED indicates that the MAC exited
|
|
|
+//! power-down mode due to a wake-on-LAN magic packet being received. This
|
|
|
+//! function call clears this flag.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint32_t
|
|
|
+EMACPowerManagementStatusGet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the control/status register and mask off the status bits to return
|
|
|
+ // them to the caller.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_PMTCTLSTAT) &
|
|
|
+ (EMAC_PMTCTLSTAT_WUPRX | EMAC_PMTCTLSTAT_MGKPRX |
|
|
|
+ EMAC_PMTCTLSTAT_PWRDWN));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables the wake-on-LAN feature of the MAC controller.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to enable the wake-on-LAN feature of the MAC
|
|
|
+//! controller. It is done by first checking if the transmit path is idle and
|
|
|
+//! disabling the trasnmitter and the transmit DMA controller. Then it checks
|
|
|
+//! if any data from the network is being actively received and if not then it
|
|
|
+//! disables the receive DMA controller.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACWoLEnter(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Check if the Transmit interrupt bit is clear.
|
|
|
+ //
|
|
|
+ while (HWREG(ui32Base + EMAC_O_DMARIS) == EMAC_DMARIS_TI)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable transmission in the MAC configuration register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_CFG) &= ~EMAC_CFG_TE;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable the MAC transmit path in the opmode register.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) &= ~EMAC_DMAOPMODE_ST;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Check if the Receive FIFO is empty.
|
|
|
+ //
|
|
|
+ while ((HWREG(ui32Base + EMAC_O_STATUS) & EMAC_STATUS_RX_FIFO_LEVEL_MASK) ==
|
|
|
+ EMAC_STATUS_RX_FIFO_EMPTY)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Disable the MAC receive path.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_DMAOPMODE) &= ~EMAC_DMAOPMODE_SR;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Configures the LPI timers and control register.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param bLPIConfig is state of LPI trasnmit automate bit.
|
|
|
+//! \param ui16LPILSTimer is the value of LS timer in milli-seconds.
|
|
|
+//! \param ui16LPITWTimer is the value of TW timer in micro-seconds.
|
|
|
+//!
|
|
|
+//! This function is used to configure the LPI timer and control registers when
|
|
|
+//! the link is established as EEE mode or when the link is lost. When the link
|
|
|
+//! is established as EEE, then \e ui16LPILSTimer is programmed as the link
|
|
|
+//! status timer value and \e ui16LPITWTimer is programmed as the transmit wait
|
|
|
+//! timer value. The parameter \e bLPIConfig is used to decide if the transmit
|
|
|
+//! path must be automated or should be under user control.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACLPIConfig(uint32_t ui32Base, bool bLPIConfig, uint16_t ui16LPILSTimer,
|
|
|
+ uint16_t ui16LPITWTimer)
|
|
|
+{
|
|
|
+ uint32_t ui32TimerValue;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ ui32TimerValue = ((ui16LPILSTimer << EMAC_LPITIMERCTL_LST_S) &
|
|
|
+ EMAC_LPITIMERCTL_LST_M);
|
|
|
+ ui32TimerValue |= ui16LPITWTimer & EMAC_LPITIMERCTL_TWT_M;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Update the LPI Timer.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_LPITIMERCTL) = ui32TimerValue;
|
|
|
+
|
|
|
+ //
|
|
|
+ // Configure the LPI Control registers.
|
|
|
+ //
|
|
|
+ if (bLPIConfig)
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_LPICTLSTAT) |= EMAC_LPICTLSTAT_LPITXA;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ HWREG(ui32Base + EMAC_O_LPICTLSTAT) = 0x0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Enables the transmit path for LPI mode entry.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to enable the transmit path in LPI mode when there
|
|
|
+//! is no more data to be transmitted by the MAC controller.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACLPIEnter(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ HWREG(ui32Base + EMAC_O_LPICTLSTAT) |= EMAC_LPICTLSTAT_LPIEN;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Returns the status of the LPI link.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function may be used to read the status of the transmit and receive
|
|
|
+//! path when the link is configured in LPI mode.
|
|
|
+//!
|
|
|
+//! \return Returns the lower 16 bits of the LPI Control and Status register.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint16_t
|
|
|
+EMACLPIStatus(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Configure the LPI Control registers.
|
|
|
+ //
|
|
|
+ return (HWREG(ui32Base + EMAC_O_LPICTLSTAT) & 0xFFFF);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Sets the link status of the external PHY.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to set the link status of the external PHY when the
|
|
|
+//! link is established in EEE mode.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACLPILinkSet(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Configure the LPI Control registers.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_LPICTLSTAT) |= EMAC_LPICTLSTAT_PLS;
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Clears the link status of the external PHY.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//!
|
|
|
+//! This function is used to clear the link status of the external PHY when the
|
|
|
+//! link is lost due to a disconnect or EEE mode link is not established.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACLPILinkClear(uint32_t ui32Base)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui32Base == EMAC0_BASE);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Configure the LPI Control registers.
|
|
|
+ //
|
|
|
+ HWREG(ui32Base + EMAC_O_LPICTLSTAT) &= ~(EMAC_LPICTLSTAT_PLS);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Writes a value to an extended PHY register in MMD address space.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui16RegAddr is the address of the PHY extended register to be
|
|
|
+//! accessed.
|
|
|
+//! \param ui16Value is the value to write to the register.
|
|
|
+//!
|
|
|
+//! When uhen connected to an external PHY supporting extended registers in MMD
|
|
|
+//! address space, this function allows a value to be written to the MMD
|
|
|
+//! register specified by \e ui16RegAddr.
|
|
|
+//!
|
|
|
+//! \return None.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+void
|
|
|
+EMACPHYMMDWrite(uint32_t ui32Base, uint8_t ui8PhyAddr, uint16_t ui16RegAddr,
|
|
|
+ uint16_t ui16Data)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the address of the register we're about to write.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_REGCTL, DEV_ADDR(ui16RegAddr));
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_ADDAR, REG_ADDR(ui16RegAddr));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Write the extended register value.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_REGCTL,
|
|
|
+ (0x4000 | DEV_ADDR(ui16RegAddr)));
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_REGCTL, ui16Data);
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+//! Reads from an extended PHY register in MMD address space.
|
|
|
+//!
|
|
|
+//! \param ui32Base is the base address of the controller.
|
|
|
+//! \param ui8PhyAddr is the physical address of the PHY to access.
|
|
|
+//! \param ui16RegAddr is the address of the PHY extended register to be
|
|
|
+//! accessed.
|
|
|
+//!
|
|
|
+//! When connected to an external PHY supporting extended registers, this
|
|
|
+//! this function returns the contents of the MMD register specified by
|
|
|
+//! \e ui16RegAddr.
|
|
|
+//!
|
|
|
+//! \return Returns the 16-bit value read from the PHY.
|
|
|
+//
|
|
|
+//*****************************************************************************
|
|
|
+uint16_t
|
|
|
+EMACPHYMMDRead(uint32_t ui32Base, uint8_t ui8PhyAddr, uint16_t ui16RegAddr)
|
|
|
+{
|
|
|
+ //
|
|
|
+ // Parameter sanity check.
|
|
|
+ //
|
|
|
+ ASSERT(ui8PhyAddr < 32);
|
|
|
+
|
|
|
+ //
|
|
|
+ // Set the address of the register we're about to read.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_REGCTL, DEV_ADDR(ui16RegAddr));
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_ADDAR, REG_ADDR(ui16RegAddr));
|
|
|
+
|
|
|
+ //
|
|
|
+ // Read the extended register value.
|
|
|
+ //
|
|
|
+ EMACPHYWrite(ui32Base, ui8PhyAddr, EPHY_REGCTL,
|
|
|
+ (0x4000 | DEV_ADDR(ui16RegAddr)));
|
|
|
+ return (EMACPHYRead(ui32Base, ui8PhyAddr, EPHY_ADDAR));
|
|
|
+}
|
|
|
+
|
|
|
+//*****************************************************************************
|
|
|
+//
|
|
|
+// Close the Doxygen group.
|
|
|
+//! @}
|
|
|
+//
|
|
|
+//*****************************************************************************
|