diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-01-07 18:31:43 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-01-07 18:31:43 +0000 |
commit | 0815fe6f374d2769bd927bc8e66fca803216e120 (patch) | |
tree | b5881b135cddbd2e4132686801758818f60fcfd7 /nuttx/arch/mips/src/pic32mx | |
parent | 6b461917d7372b8956927bfa5a7cab068383c9f6 (diff) | |
download | px4-nuttx-0815fe6f374d2769bd927bc8e66fca803216e120.tar.gz px4-nuttx-0815fe6f374d2769bd927bc8e66fca803216e120.tar.bz2 px4-nuttx-0815fe6f374d2769bd927bc8e66fca803216e120.zip |
Add PIC32 Ethernet driver (initial is just crude LPC17xx port)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4276 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/mips/src/pic32mx')
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.c | 2509 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.h | 722 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h | 49 |
4 files changed, 3175 insertions, 109 deletions
diff --git a/nuttx/arch/mips/src/pic32mx/Make.defs b/nuttx/arch/mips/src/pic32mx/Make.defs index 3aee3179f..504348c60 100644 --- a/nuttx/arch/mips/src/pic32mx/Make.defs +++ b/nuttx/arch/mips/src/pic32mx/Make.defs @@ -73,3 +73,7 @@ endif ifeq ($(CONFIG_PIC32MX_USBDEV),y) CHIP_CSRCS += pic32mx-usbdev.c endif + +ifeq ($(CONFIG_PIC32MX_ETHERNET),y) +CHIP_CSRCS += pic32mx-ethernet.c +endif diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.c b/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.c new file mode 100644 index 000000000..581ca9e36 --- /dev/null +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.c @@ -0,0 +1,2509 @@ +/**************************************************************************** + * arch/arm/src/pic32mx/pic32mx_ethernet.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * This driver derives from the PIC32MX Ethernet Driver + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#if defined(CONFIG_NET) && defined(CONFIG_PIC32MX_ETHERNET) + +#include <stdint.h> +#include <stdbool.h> +#include <time.h> +#include <string.h> +#include <debug.h> +#include <wdog.h> +#include <errno.h> + +#include <nuttx/irq.h> +#include <nuttx/arch.h> +#include <nuttx/mii.h> + +#include <net/uip/uip.h> +#include <net/uip/uipopt.h> +#include <net/uip/uip-arp.h> +#include <net/uip/uip-arch.h> + +#include "chip.h" +#include "up_arch.h" +#include "pic32mx-ethernet.h" +#include "pic32mx-internal.h" + +#include <arch/board/board.h> + +/* Does this chip have and ethernet controller? */ + +#if CHIP_NETHERNET > 0 + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* CONFIG_PIC32MX_NINTERFACES determines the number of physical interfaces + * that will be supported -- unless it is more than actually supported by the + * hardware! + */ + +#if !defined(CONFIG_PIC32MX_NINTERFACES) || CONFIG_PIC32MX_NINTERFACES > CHIP_NETHERNET +# undef CONFIG_PIC32MX_NINTERFACES +# define CONFIG_PIC32MX_NINTERFACES CHIP_NETHERNET +#endif + +/* The logic here has a few hooks for support for multiple interfaces, but + * that capability is not yet in place (and I won't worry about it until I get + * the first multi-interface PIC32MX). + */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# warning "Only a single ethernet controller is supported" +# undef CONFIG_PIC32MX_NINTERFACES +# define CONFIG_PIC32MX_NINTERFACES 1 +#endif + +/* If IGMP is enabled, then accept multi-cast frames. */ + +#if defined(CONFIG_NET_IGMP) && !defined(CONFIG_NET_MULTICAST) +# define CONFIG_NET_MULTICAST 1 +#endif + +/* If the user did not specify a priority for Ethernet interrupts, set the + * interrupt priority to the maximum. + */ + +#ifndef CONFIG_NET_PRIORITY +# define CONFIG_NET_PRIORITY NVIC_SYSH_PRIORITY_MAX +#endif + +/* Debug Configuration *****************************************************/ +/* Register debug -- can only happen of CONFIG_DEBUG is selected */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_REGDEBUG +#endif + +/* CONFIG_NET_DUMPPACKET will dump the contents of each packet to the + * console. + */ + +#ifndef CONFIG_DEBUG +# undef CONFIG_NET_DUMPPACKET +#endif + +#ifdef CONFIG_NET_DUMPPACKET +# define pic32mx_dumppacket(m,a,n) lib_dumpbuffer(m,a,n) +#else +# define pic32mx_dumppacket(m,a,n) +#endif + +/* Timing *******************************************************************/ + +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define PIC32MX_WDDELAY (1*CLK_TCK) +#define PIC32MX_POLLHSEC (1*2) + +/* TX timeout = 1 minute */ + +#define PIC32MX_TXTIMEOUT (60*CLK_TCK) + +/* Interrupts ***************************************************************/ + +#define ETH_RXINTS (ETH_INT_RXOVR | ETH_INT_RXERR | ETH_INT_RXFIN | ETH_INT_RXDONE) +#define ETH_TXINTS (ETH_INT_TXUNR | ETH_INT_TXERR | ETH_INT_TXFIN | ETH_INT_TXDONE) + +/* Misc. Helpers ***********************************************************/ + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct uip_eth_hdr *)priv->pd_dev.d_buf) + +/* This is the number of ethernet GPIO pins that must be configured */ + +#define GPIO_NENET_PINS 10 + +/* PHYs *********************************************************************/ +/* Select PHY-specific values. Add more PHYs as needed. */ + +#if defined(CONFIG_PHY_KS8721) +# define PIC32MX_PHYNAME "KS8721" +# define PIC32MX_PHYID1 MII_PHYID1_KS8721 +# define PIC32MX_PHYID2 MII_PHYID2_KS8721 +# define PIC32MX_HAVE_PHY 1 +#elif defined(CONFIG_PHY_DP83848C) +# define PIC32MX_PHYNAME "DP83848C" +# define PIC32MX_PHYID1 MII_PHYID1_DP83848C +# define PIC32MX_PHYID2 MII_PHYID2_DP83848C +# define PIC32MX_HAVE_PHY 1 +#elif defined(CONFIG_PHY_LAN8720) +# define PIC32MX_PHYNAME "LAN8720" +# define PIC32MX_PHYID1 MII_PHYID1_LAN8720 +# define PIC32MX_PHYID2 MII_PHYID2_LAN8720 +# define PIC32MX_HAVE_PHY 1 +#else +# warning "No PHY specified!" +# undef PIC32MX_HAVE_PHY +#endif + +#define MII_BIG_TIMEOUT 666666 + +/* These definitions are used to remember the speed/duplex settings */ + +#define PIC32MX_SPEED_MASK 0x01 +#define PIC32MX_SPEED_100 0x01 +#define PIC32MX_SPEED_10 0x00 + +#define PIC32MX_DUPLEX_MASK 0x02 +#define PIC32MX_DUPLEX_FULL 0x02 +#define PIC32MX_DUPLEX_HALF 0x00 + +#define PIC32MX_10BASET_HD (PIC32MX_SPEED_10 | PIC32MX_DUPLEX_HALF) +#define PIC32MX_10BASET_FD (PIC32MX_SPEED_10 | PIC32MX_DUPLEX_FULL) +#define PIC32MX_100BASET_HD (PIC32MX_SPEED_100 | PIC32MX_DUPLEX_HALF) +#define PIC32MX_100BASET_FD (PIC32MX_SPEED_100 | PIC32MX_DUPLEX_FULL) + +#ifdef CONFIG_PHY_SPEED100 +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MX_MODE_DEFLT PIC32MX_100BASET_FD +# else +# define PIC32MX_MODE_DEFLT PIC32MX_100BASET_HD +# endif +#else +# ifdef CONFIG_PHY_FDUPLEX +# define PIC32MX_MODE_DEFLT PIC32MX_10BASET_FD +# else +# define PIC32MX_MODE_DEFLT PIC32MX_10BASET_HD +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* EMAC statistics (debug only) */ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) +struct pic32mx_statistics_s +{ +#ifdef ENABLE_WOL + uint32_t wol; /* Wake-up interrupts */ +#endif + uint32_t rx_finished; /* Rx finished interrupts */ + uint32_t rx_done; /* Rx done interrupts */ + uint32_t rx_ovrerrors; /* Number of Rx overrun error interrupts */ + uint32_t rx_errors; /* Number of Rx error interrupts (OR of other errors) */ + uint32_t rx_packets; /* Number of packets received (sum of the following): */ + uint32_t rx_ip; /* Number of Rx IP packets received */ + uint32_t rx_arp; /* Number of Rx ARP packets received */ + uint32_t rx_dropped; /* Number of dropped, unsupported Rx packets */ + uint32_t rx_pkterr; /* Number of dropped, error in Rx descriptor */ + uint32_t rx_pktsize; /* Number of dropped, too small or too big */ + uint32_t rx_fragment; /* Number of dropped, packet fragments */ + + uint32_t tx_packets; /* Number of Tx packets queued */ + uint32_t tx_pending; /* Number of Tx packets that had to wait for a TxDesc */ + uint32_t tx_unpend; /* Number of pending Tx packets that were sent */ + uint32_t tx_finished; /* Tx finished interrupts */ + uint32_t tx_done; /* Tx done interrupts */ + uint32_t tx_underrun; /* Number of Tx underrun error interrupts */ + uint32_t tx_errors; /* Number of Tx error inerrupts (OR of other errors) */ + uint32_t tx_timeouts; /* Number of Tx timeout errors */ +}; +# define EMAC_STAT(priv,name) priv->pd_stat.name++ +#else +# define EMAC_STAT(priv,name) +#endif + +/* The pic32mx_driver_s encapsulates all state information for a single hardware + * interface + */ + +struct pic32mx_driver_s +{ + /* The following fields would only be necessary on chips that support + * multiple Ethernet controllers. + */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + uint32_t pd_base; /* Ethernet controller base address */ + int pd_irq; /* Ethernet controller IRQ vector number */ + int pd_irqsrc; /* Ethernet controller IRQ source number */ +#endif + + bool pd_ifup; /* true:ifup false:ifdown */ + bool pd_mode; /* speed/duplex */ + bool pd_txpending; /* There is a pending Tx in pd_dev */ +#ifdef PIC32MX_HAVE_PHY + uint8_t pd_phyaddr; /* PHY device address */ +#endif + uint32_t pd_inten; /* Shadow copy of INTEN register */ + WDOG_ID pd_txpoll; /* TX poll timer */ + WDOG_ID pd_txtimeout; /* TX timeout timer */ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) + struct pic32mx_statistics_s pd_stat; +#endif + + /* This holds the information visible to uIP/NuttX */ + + struct uip_driver_s pd_dev; /* Interface understood by uIP */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Array of ethernet driver status structures */ + +static struct pic32mx_driver_s g_ethdrvr[CONFIG_PIC32MX_NINTERFACES]; + +/* ENET pins are on P1[0,1,4,6,8,9,10,14,15] + MDC on P1[16] or P2[8] and + * MDIO on P1[17] or P2[9]. The board.h file will define GPIO_ENET_MDC and + * PGIO_ENET_MDIO to selec which pin setting to use. + * + * On older Rev '-' devices, P1[6] ENET-TX_CLK would also have be to configured. + */ + +static const uint16_t g_enetpins[GPIO_NENET_PINS] = +{ + GPIO_ENET_TXD0, GPIO_ENET_TXD1, GPIO_ENET_TXEN, GPIO_ENET_CRS, GPIO_ENET_RXD0, + GPIO_ENET_RXD1, GPIO_ENET_RXER, GPIO_ENET_REFCLK, GPIO_ENET_MDC, GPIO_ENET_MDIO +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations */ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void pic32mx_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t pic32mx_getreg(uint32_t addr); +static void pic32mx_putreg(uint32_t val, uint32_t addr); +#else +# define pic32mx_getreg(addr) getreg32(addr) +# define pic32mx_putreg(val,addr) putreg32(val,addr) +#endif + +/* Common TX logic */ + +static int pic32mx_txdesc(struct pic32mx_driver_s *priv); +static int pic32mx_transmit(struct pic32mx_driver_s *priv); +static int pic32mx_uiptxpoll(struct uip_driver_s *dev); + +/* Interrupt handling */ + +static void pic32mx_response(struct pic32mx_driver_s *priv); +static void pic32mx_rxdone(struct pic32mx_driver_s *priv); +static void pic32mx_txdone(struct pic32mx_driver_s *priv); +static int pic32mx_interrupt(int irq, void *context); + +/* Watchdog timer expirations */ + +static void pic32mx_polltimer(int argc, uint32_t arg, ...); +static void pic32mx_txtimeout(int argc, uint32_t arg, ...); + +/* NuttX callback functions */ + +static int pic32mx_ifup(struct uip_driver_s *dev); +static int pic32mx_ifdown(struct uip_driver_s *dev); +static int pic32mx_txavail(struct uip_driver_s *dev); +#ifdef CONFIG_NET_IGMP +static int pic32mx_addmac(struct uip_driver_s *dev, const uint8_t *mac); +static int pic32mx_rmmac(struct uip_driver_s *dev, const uint8_t *mac); +#endif + +/* Initialization functions */ + +#if defined(CONFIG_NET_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +static void pic32mx_showpins(void); +#else +# define pic32mx_showpins() +#endif + +/* PHY initialization functions */ + +#ifdef PIC32MX_HAVE_PHY +# ifdef CONFIG_NET_REGDEBUG +static void pic32mx_showmii(uint8_t phyaddr, const char *msg); +# else +# define pic32mx_showmii(phyaddr,msg) +# endif + +static void pic32mx_phywrite(uint8_t phyaddr, uint8_t regaddr, + uint16_t phydata); +static uint16_t pic32mx_phyread(uint8_t phyaddr, uint8_t regaddr); +static inline int pic32mx_phyreset(uint8_t phyaddr); +# ifdef CONFIG_PHY_AUTONEG +static inline int pic32mx_phyautoneg(uint8_t phyaddr); +# endif +static int pic32mx_phymode(uint8_t phyaddr, uint8_t mode); +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv); +#else +# define pic32mx_phyinit(priv) +#endif + +/* EMAC Initialization functions */ + +static inline void pic32mx_txdescinit(struct pic32mx_driver_s *priv); +static inline void pic32mx_rxdescinit(struct pic32mx_driver_s *priv); +static void pic32mx_macmode(uint8_t mode); +static void pic32mx_ethreset(struct pic32mx_driver_s *priv); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/******************************************************************************* + * Name: pic32mx_printreg + * + * Description: + * Print the contents of an PIC32MX register operation + * + *******************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + dbg("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/******************************************************************************* + * Name: pic32mx_checkreg + * + * Description: + * Get the contents of an PIC32MX register + * + *******************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + pic32mx_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + dbg("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + pic32mx_printreg(addr, val, iswrite); + } +} +#endif + +/******************************************************************************* + * Name: pic32mx_getreg + * + * Description: + * Get the contents of an PIC32MX register + * + *******************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static uint32_t pic32mx_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + pic32mx_checkreg(addr, val, false); + return val; +} +#endif + +/******************************************************************************* + * Name: pic32mx_putreg + * + * Description: + * Set the contents of an PIC32MX register to a value + * + *******************************************************************************/ + +#ifdef CONFIG_NET_REGDEBUG +static void pic32mx_putreg(uint32_t val, uint32_t addr) +{ + /* Check if we need to print this value */ + + pic32mx_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Function: pic32mx_txdesc + * + * Description: + * Check if a free TX descriptor is available. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mx_txdesc(struct pic32mx_driver_s *priv) +{ + unsigned int prodidx; + unsigned int considx; + + /* Get the next producer index */ + + prodidx = pic32mx_getreg(PIC32MX_ETH_TXPRODIDX) & ETH_TXPRODIDX_MASK; + if (++prodidx >= CONFIG_NET_NTXDESC) + { + /* Wrap back to index zero */ + + prodidx = 0; + } + + /* If the next producer index would overrun the consumer index, then there + * are no available Tx descriptors. + */ + + considx = pic32mx_getreg(PIC32MX_ETH_TXCONSIDX) & ETH_TXCONSIDX_MASK; + return prodidx != considx ? OK : -EAGAIN; +} + +/**************************************************************************** + * Function: pic32mx_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mx_transmit(struct pic32mx_driver_s *priv) +{ + uint32_t *txdesc; + void *txbuffer; + unsigned int prodidx; + + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + DEBUGASSERT(pic32mx_txdesc(priv) == OK); + + /* Increment statistics and dump the packet *if so configured) */ + + EMAC_STAT(priv, tx_packets); + pic32mx_dumppacket("Transmit packet", + priv->pd_dev.d_buf, priv->pd_dev.d_len); + + /* Get the current producer index */ + + prodidx = pic32mx_getreg(PIC32MX_ETH_TXPRODIDX) & ETH_TXPRODIDX_MASK; + + /* Get the packet address from the descriptor and set the descriptor control + * fields. + */ + + txdesc = (uint32_t*)(PIC32MX_TXDESC_BASE + (prodidx << 3)); + txbuffer = (void*)*txdesc++; + *txdesc = TXDESC_CONTROL_INT | TXDESC_CONTROL_LAST | TXDESC_CONTROL_CRC | + (priv->pd_dev.d_len - 1); + + /* Copy the packet data into the Tx buffer assignd to this descriptor. It + * should fit because each packet buffer is the MTU size and breaking up + * largerTCP messasges is handled by higher level logic. The hardware + * does, however, support breaking up larger messages into many fragments, + * however, that capability is not exploited here. + * + * This would be a great performance improvement: Remove the buffer from + * the pd_dev structure and replace it a pointer directly into the EMAC + * DMA memory. This could eliminate the following, costly memcpy. + */ + + DEBUGASSERT(priv->pd_dev.d_len <= PIC32MX_MAXPACKET_SIZE); + memcpy(txbuffer, priv->pd_dev.d_buf, priv->pd_dev.d_len); + + /* Bump the producer index, making the packet available for transmission. */ + + if (++prodidx >= CONFIG_NET_NTXDESC) + { + /* Wrap back to index zero */ + + prodidx = 0; + } + pic32mx_putreg(prodidx, PIC32MX_ETH_TXPRODIDX); + + /* Enable Tx interrupts */ + + priv->pd_inten |= ETH_TXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_INTEN); + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->pd_txtimeout, PIC32MX_TXTIMEOUT, pic32mx_txtimeout, + 1, (uint32_t)priv); + return OK; +} + +/**************************************************************************** + * Function: pic32mx_uiptxpoll + * + * Description: + * The transmitter is available, check if uIP has any outgoing packets ready + * to send. This is a callback from uip_poll(). uip_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * global interrupts are disabled, either explicitly or indirectly through + * interrupt handling logic. + * + ****************************************************************************/ + +static int pic32mx_uiptxpoll(struct uip_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + int ret = OK; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + /* Send this packet. In this context, we know that there is space for + * at least one more packet in the descriptor list. + */ + + uip_arp_out(&priv->pd_dev); + pic32mx_transmit(priv); + + /* Check if there is room in the device to hold another packet. If not, + * return any non-zero value to terminate the poll. + */ + + ret = pic32mx_txdesc(priv); + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return ret; +} + +/**************************************************************************** + * Function: pic32mx_response + * + * Description: + * While processing an RxDone event, higher logic decides to send a packet, + * possibly a response to the incoming packet (but probably not, in reality). + * However, since the Rx and Tx operations are decoupled, there is no + * guarantee that there will be a Tx descriptor available at that time. + * This function will perform that check and, if no Tx descriptor is + * available, this function will (1) stop incoming Rx processing (bad), and + * (2) hold the outgoing packet in a pending state until the next Tx + * interrupt occurs. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_response(struct pic32mx_driver_s *priv) +{ + int ret; + + /* Check if there is room in the device to hold another packet. */ + + ret = pic32mx_txdesc(priv); + if (ret == OK) + { + /* Yes.. queue the packet now. */ + + pic32mx_transmit(priv); + } + else + { + /* No.. mark the Tx as pending and halt further Tx interrupts */ + + DEBUGASSERT((priv->pd_inten & ETH_INT_TXDONE) != 0); + + priv->pd_txpending = true; + priv->pd_inten &= ~ETH_RXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_INTEN); + EMAC_STAT(priv, tx_pending); + } +} + +/**************************************************************************** + * Function: pic32mx_rxdone + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_rxdone(struct pic32mx_driver_s *priv) +{ + uint32_t *rxstat; + bool fragment; + unsigned int prodidx; + unsigned int considx; + unsigned int pktlen; + + /* Get the current producer and consumer indices */ + + considx = pic32mx_getreg(PIC32MX_ETH_RXCONSIDX) & ETH_RXCONSIDX_MASK; + prodidx = pic32mx_getreg(PIC32MX_ETH_RXPRODIDX) & ETH_RXPRODIDX_MASK; + + /* Loop while there are incoming packets to be processed, that is, while + * the producer index is not equal to the consumer index. + */ + + fragment = false; + while (considx != prodidx) + { + /* Update statistics */ + + EMAC_STAT(priv, rx_packets); + + /* Get the Rx status and packet length (-4+1) */ + + rxstat = (uint32_t*)(PIC32MX_RXSTAT_BASE + (considx << 3)); + pktlen = (*rxstat & RXSTAT_INFO_RXSIZE_MASK) - 3; + + /* Check for errors. NOTE: The DMA engine reports bogus length errors, + * making this a pretty useless check. + */ + + if ((*rxstat & RXSTAT_INFO_ERROR) != 0) + { + nlldbg("Error. considx: %08x prodidx: %08x rxstat: %08x\n", + considx, prodidx, *rxstat); + EMAC_STAT(priv, rx_pkterr); + } + + /* If the pktlen is greater then the buffer, then we cannot accept + * the packet. Also, since the DMA packet buffers are set up to + * be the same size as our max packet size, any fragments also + * imply that the packet is too big. + */ + + /* else */ if (pktlen > CONFIG_NET_BUFSIZE + CONFIG_NET_GUARDSIZE) + { + nlldbg("Too big. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + EMAC_STAT(priv, rx_pktsize); + } + else if ((*rxstat & RXSTAT_INFO_LASTFLAG) == 0) + { + nlldbg("Fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + EMAC_STAT(priv, rx_fragment); + fragment = true; + } + else if (fragment) + { + nlldbg("Last fragment. considx: %08x prodidx: %08x pktlen: %d rxstat: %08x\n", + considx, prodidx, pktlen, *rxstat); + EMAC_STAT(priv, rx_fragment); + fragment = false; + } + else + { + uint32_t *rxdesc; + void *rxbuffer; + + /* Get the Rx buffer address from the Rx descriptor */ + + rxdesc = (uint32_t*)(PIC32MX_RXDESC_BASE + (considx << 3)); + rxbuffer = (void*)*rxdesc; + + /* Copy the data data from the EMAC DMA RAM to priv->pd_dev.d_buf. + * Set amount of data in priv->pd_dev.d_len + * + * Here would be a great performance improvement: Remove the + * buffer from the pd_dev structure and replace it with a pointer + * directly into the EMAC DMA memory. This could eliminate the + * following, costly memcpy. + */ + + memcpy(priv->pd_dev.d_buf, rxbuffer, pktlen); + priv->pd_dev.d_len = pktlen; + + pic32mx_dumppacket("Received packet", + priv->pd_dev.d_buf, priv->pd_dev.d_len); + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(UIP_ETHTYPE_IP6)) +#else + if (BUF->type == HTONS(UIP_ETHTYPE_IP)) +#endif + { + /* Handle the incoming Rx packet */ + + EMAC_STAT(priv, rx_ip); + uip_arp_ipin(&priv->pd_dev); + uip_input(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + uip_arp_out(&priv->pd_dev); + pic32mx_response(priv); + } + } + else if (BUF->type == htons(UIP_ETHTYPE_ARP)) + { + EMAC_STAT(priv, rx_arp); + uip_arp_arpin(&priv->pd_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the field d_len will + * set to a value > 0. + */ + + if (priv->pd_dev.d_len > 0) + { + pic32mx_response(priv); + } + } + else + { + /* Unrecognized... drop it. */ + + EMAC_STAT(priv, rx_dropped); + } + } + + /* Bump up the consumer index and resample the producer index (which + * might also have gotten bumped up by the hardware). + */ + + if (++considx >= CONFIG_NET_NRXDESC) + { + /* Wrap back to index zero */ + + considx = 0; + } + + pic32mx_putreg(considx, PIC32MX_ETH_RXCONSIDX); + prodidx = pic32mx_getreg(PIC32MX_ETH_RXPRODIDX) & ETH_RXPRODIDX_MASK; + } +} + +/**************************************************************************** + * Function: pic32mx_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by interrupt handling logic. + * + ****************************************************************************/ + +static void pic32mx_txdone(struct pic32mx_driver_s *priv) +{ + /* Cancel the pending Tx timeout */ + + wd_cancel(priv->pd_txtimeout); + + /* Disable further Tx interrupts. Tx interrupts may be re-enabled again + * depending upon the result of the poll. + */ + + priv->pd_inten &= ~ETH_TXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_INTEN); + + /* Verify that the hardware is ready to send another packet. Since a Tx + * just completed, this must be the case. + */ + + DEBUGASSERT(pic32mx_txdesc(priv) == OK); + + /* Check if there is a pending Tx transfer that was scheduled by Rx handling + * while the Tx logic was busy. If so, processing that pending Tx now. + */ + + if (priv->pd_txpending) + { + /* Clear the pending condition, send the packet, and restore Rx interrupts */ + + priv->pd_txpending = false; + EMAC_STAT(priv, tx_unpend); + + pic32mx_transmit(priv); + + priv->pd_inten |= ETH_RXINTS; + pic32mx_putreg(priv->pd_inten, PIC32MX_ETH_INTEN); + } + + /* Otherwise poll uIP for new XMIT data */ + + else + { + (void)uip_poll(&priv->pd_dev, pic32mx_uiptxpoll); + } +} + +/**************************************************************************** + * Function: pic32mx_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_interrupt(int irq, void *context) +{ + register struct pic32mx_driver_s *priv; + uint32_t status; + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# error "A mechanism to associate and interface with an IRQ is needed" +#else + priv = &g_ethdrvr[0]; +#endif + + /* Get the interrupt status (zero means no interrupts pending). */ + + status = pic32mx_getreg(PIC32MX_ETH_INTST); + if (status != 0) + { + /* Clear all pending interrupts */ + + pic32mx_putreg(status, PIC32MX_ETH_INTCLR); + + /* Handle each pending interrupt **************************************/ + /* Check for Wake-Up on Lan *******************************************/ + +#ifdef CONFIG_NET_WOL + if ((status & ETH_INT_WKUP) != 0) + { + EMAC_STAT(priv, wol); +# warning "Missing logic" + } + else +#endif + /* Fatal Errors *******************************************************/ + /* RX OVERRUN -- Fatal overrun error in the receive queue. The fatal + * interrupt should be resolved by a Rx soft-reset. The bit is not + * set when there is a nonfatal overrun error. + * + * TX UNDERRUN -- Interrupt set on a fatal underrun error in the + * transmit queue. The fatal interrupt should be resolved by a Tx + * soft-reset. The bit is not set when there is a nonfatal underrun + * error. + */ + + if ((status & (ETH_INT_RXOVR|ETH_INT_TXUNR)) != 0) + { + if ((status & ETH_INT_RXOVR) != 0) + { + nlldbg("RX Overrun. status: %08x\n", status); + EMAC_STAT(priv, rx_ovrerrors); + } + + if ((status & ETH_INT_TXUNR) != 0) + { + nlldbg("TX Underrun. status: %08x\n", status); + EMAC_STAT(priv, tx_underrun); + } + + /* ifup() will reset the EMAC and bring it back up */ + + (void)pic32mx_ifup(&priv->pd_dev); + } + else + { + /* Check for receive events ***************************************/ + /* RX ERROR -- Triggered on receive errors: AlignmentError, + * RangeError, LengthError, SymbolError, CRCError or NoDescriptor + * or Overrun. NOTE: (1) We will still need to call pic32mx_rxdone + * on RX errors to bump the considx over the bad packet. (2) The + * DMA engine reports bogus length errors, making this a pretty + * useless check anyway. + */ + + if ((status & ETH_INT_RXERR) != 0) + { + nlldbg("RX Error. status: %08x\n", status); + EMAC_STAT(priv, rx_errors); + } + + /* RX FINISHED -- Triggered when all receive descriptors have + * been processed i.e. on the transition to the situation + * where ProduceIndex == ConsumeIndex. + */ + + if ((status & ETH_INT_RXFIN) != 0) + { + EMAC_STAT(priv, rx_finished); + DEBUGASSERT(pic32mx_getreg(PIC32MX_ETH_RXPRODIDX) == pic32mx_getreg(PIC32MX_ETH_RXCONSIDX)); + } + + /* RX DONE -- Triggered when a receive descriptor has been + * processed while the Interrupt bit in the Control field of + * the descriptor was set. + */ + + if ((status & ETH_INT_RXDONE) != 0) + { + EMAC_STAT(priv, rx_done); + + /* We have received at least one new incoming packet. */ + + pic32mx_rxdone(priv); + } + + /* Check for Tx events ********************************************/ + /* TX ERROR -- Triggered on transmit errors: LateCollision, + * ExcessiveCollision and ExcessiveDefer, NoDescriptor or Underrun. + * NOTE: We will still need to call pic32mx_txdone() in order to + * clean up after the failed transmit. + */ + + if ((status & ETH_INT_TXERR) != 0) + { + nlldbg("TX Error. status: %08x\n", status); + EMAC_STAT(priv, tx_errors); + } + + /* TX FINISHED -- Triggered when all transmit descriptors have + * been processed i.e. on the transition to the situation + * where ProduceIndex == ConsumeIndex. + */ + + if ((status & ETH_INT_TXFIN) != 0) + { + EMAC_STAT(priv, tx_finished); + } + + /* TX DONE -- Triggered when a descriptor has been transmitted + * while the Interrupt bit in the Control field of the + * descriptor was set. + */ + + if ((status & ETH_INT_TXDONE) != 0) + { + EMAC_STAT(priv, tx_done); + + /* A packet transmission just completed */ + + pic32mx_txdone(priv); + } + } + } + + /* Clear the pending interrupt */ + +#if 0 /* Apparently not necessary */ +# if CONFIG_PIC32MX_NINTERFACES > 1 + pic32mx_clrpend(priv->pd_irqsrc); +# else + pic32mx_clrpend(PIC32MX_IRQSRC_ETH); +# endif +#endif + + return OK; +} + +/**************************************************************************** + * Function: pic32mx_txtimeout + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mx_txtimeout(int argc, uint32_t arg, ...) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg; + + /* Increment statistics and dump debug info */ + + EMAC_STAT(priv, tx_timeouts); + if (priv->pd_ifup) + { + /* Then reset the hardware. ifup() will reset the interface, then bring + * it back up. + */ + + (void)pic32mx_ifup(&priv->pd_dev); + + /* Then poll uIP for new XMIT data */ + + (void)uip_poll(&priv->pd_dev, pic32mx_uiptxpoll); + } +} + +/**************************************************************************** + * Function: pic32mx_polltimer + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void pic32mx_polltimer(int argc, uint32_t arg, ...) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg; + + /* Check if there is room in the send another TX packet. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ + + if (pic32mx_txdesc(priv) == OK) + { + /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm.. + * might be bug here. Does this mean if there is a transmit in progress, + * we will missing TCP time state updates? + */ + + (void)uip_timer(&priv->pd_dev, pic32mx_uiptxpoll, PIC32MX_POLLHSEC); + } + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_polltimer, 1, arg); +} + +/**************************************************************************** + * Function: pic32mx_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_ifup(struct uip_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + uint32_t regval; + int ret; + + ndbg("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); + + /* Reset the Ethernet controller (again) */ + + pic32mx_ethreset(priv); + + /* Initialize the PHY and wait for the link to be established */ + + ret = pic32mx_phyinit(priv); + if (ret != 0) + { + ndbg("pic32mx_phyinit failed: %d\n", ret); + return ret; + } + + /* Configure the MAC station address */ + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[5] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[4]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA0); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[3] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[2]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA1); + + regval = (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[1] << 8 | + (uint32_t)priv->pd_dev.d_mac.ether_addr_octet[0]; + pic32mx_putreg(regval, PIC32MX_EMAC1_SA2); + + /* Initialize Ethernet interface for the PHY setup */ + + pic32mx_macmode(priv->pd_mode); + + /* Initialize EMAC DMA memory -- descriptors, status, packet buffers, etc. */ + + pic32mx_txdescinit(priv); + pic32mx_rxdescinit(priv); + + /* Configure to pass all received frames */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_CFG1); + regval |= EMAC1_CFG1_PASSALL; + pic32mx_putreg(regval, PIC32MX_EMAC1_CFG1); + + /* Set up RX filter and configure to accept broadcast addresses, multicast + * addresses, and perfect station address matches. We should also accept + * perfect matches and, most likely, broadcast (for example, for ARP requests). + * Other RX filter options will only be enabled if so selected. NOTE: There + * is a selection CONFIG_NET_BROADCAST, but this enables receipt of UDP + * broadcast packets inside of the stack. + */ + + regval = ETH_RXFLCTRL_PERFEN | ETH_RXFLCTRL_BCASTEN; +#ifdef CONFIG_NET_MULTICAST + RXFILTERCTRL |= (ETH_RXFLCTRL_MCASTEN | ETH_RXFLCTRL_UCASTEN); +#endif +#ifdef CONFIG_NET_HASH + RXFILTERCTRL |= (ETH_RXFLCTRL_MCASTHASHEN | ETH_RXFLCTRL_UCASTHASHEN); +#endif + pic32mx_putreg(regval, PIC32MX_ETH_RXFLCTRL); + + /* Clear any pending interrupts (shouldn't be any) */ + + pic32mx_putreg(0xffffffff, PIC32MX_ETH_INTCLR); + + /* Configure interrupts. The Ethernet interrupt was attached during one-time + * initialization, so we only need to set the interrupt priority, configure + * interrupts, and enable them. + */ + + /* Set the interrupt to the highest priority */ + +#ifdef CONFIG_ARCH_IRQPRIO +#if CONFIG_PIC32MX_NINTERFACES > 1 + (void)up_prioritize_irq(priv->pd_irq, CONFIG_NET_PRIORITY); +#else + (void)up_prioritize_irq(PIC32MX_IRQ_ETH, CONFIG_NET_PRIORITY); +#endif +#endif + + /* Enable Ethernet interrupts. The way we do this depends on whether or + * not Wakeup on Lan (WoL) has been configured. + */ + +#ifdef CONFIG_NET_WOL + /* Configure WoL: Clear all receive filter WoLs and enable the perfect + * match WoL interrupt. We will wait until the Wake-up to finish + * bringing things up. + */ + + pic32mx_putreg(0xffffffff, PIC32MX_ETH_RXFLWOLCLR); + pic32mx_putreg(ETH_RXFLCTRL_RXFILEN, PIC32MX_ETH_RXRLCTRL); + + priv->pd_inten = ETH_INT_WKUP; + pic32mx_putreg(ETH_INT_WKUP, PIC32MX_ETH_INTEN); +#else + /* Otherwise, enable all Rx interrupts. Tx interrupts, SOFTINT and WoL are + * excluded. Tx interrupts will not be enabled until there is data to be + * sent. + */ + + priv->pd_inten = ETH_RXINTS; + pic32mx_putreg(ETH_RXINTS, PIC32MX_ETH_INTEN); +#endif + + /* Enable Rx. "Enabling of the receive function is located in two places. + * The receive DMA manager needs to be enabled and the receive data path + * of the MAC needs to be enabled. To prevent overflow in the receive + * DMA engine the receive DMA engine should be enabled by setting the + * RxEnable bit in the Command register before enabling the receive data + * path in the MAC by setting the RECEIVE ENABLE bit in the MAC1 register." + */ + + regval = pic32mx_getreg(PIC32MX_ETH_CMD); + regval |= ETH_CMD_RXEN; + pic32mx_putreg(regval, PIC32MX_ETH_CMD); + + regval = pic32mx_getreg(PIC32MX_EMAC1_CFG1); + regval |= EMAC1_CFG1_RE; + pic32mx_putreg(regval, PIC32MX_EMAC1_CFG1); + + /* Enable Tx */ + + regval = pic32mx_getreg(PIC32MX_ETH_CMD); + regval |= ETH_CMD_TXEN; + pic32mx_putreg(regval, PIC32MX_ETH_CMD); + + /* Set and activate a timer process */ + + (void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_polltimer, 1, + (uint32_t)priv); + + /* Finally, make the interface up and enable the Ethernet interrupt at + * the interrupt controller + */ + + priv->pd_ifup = true; +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_enable_irq(priv->pd_irqsrc); +#else + up_enable_irq(PIC32MX_IRQSRC_ETH); +#endif + return OK; +} + +/**************************************************************************** + * Function: pic32mx_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int pic32mx_ifdown(struct uip_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = irqsave(); +#if CONFIG_PIC32MX_NINTERFACES > 1 + up_disable_irq(priv->pd_irqsrc); +#else + up_disable_irq(PIC32MX_IRQSRC_ETH); +#endif + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->pd_txpoll); + wd_cancel(priv->pd_txtimeout); + + /* Reset the device and mark it as down. */ + + pic32mx_ethreset(priv); + priv->pd_ifup = false; + irqrestore(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mx_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int pic32mx_txavail(struct uip_driver_s *dev) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable interrupts because this function may be called from interrupt + * level processing. + */ + + flags = irqsave(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->pd_ifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ + + if (pic32mx_txdesc(priv) == OK) + { + /* If so, then poll uIP for new XMIT data */ + + (void)uip_poll(&priv->pd_dev, pic32mx_uiptxpoll); + } + } + + irqrestore(flags); + return OK; +} + +/**************************************************************************** + * Function: pic32mx_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mx_addmac(struct uip_driver_s *dev, const uint8_t *mac) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mx_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int pic32mx_rmmac(struct uip_driver_s *dev, const uint8_t *mac) +{ + struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ + +#warning "Not implemented" + return OK; +} +#endif + +/******************************************************************************* + * Name: pic32mx_showpins + * + * Description: + * Dump GPIO registers + * + * Parameters: + * None + * + * Returned Value: + * None + * + * Assumptions: + * + *******************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(CONFIG_DEBUG_GPIO) +static void pic32mx_showpins(void) +{ + pic32mx_dumpgpio(GPIO_PORT1|GPIO_PIN0, "P1[1-15]"); + pic32mx_dumpgpio(GPIO_PORT1|GPIO_PIN16, "P1[16-31]"); +} +#endif + +/******************************************************************************* + * Name: pic32mx_showmii + * + * Description: + * Dump PHY MII registers + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + *******************************************************************************/ + +#if defined(CONFIG_NET_REGDEBUG) && defined(PIC32MX_HAVE_PHY) +static void pic32mx_showmii(uint8_t phyaddr, const char *msg) +{ + dbg("PHY " PIC32MX_PHYNAME ": %s\n", msg); + dbg(" MCR: %04x\n", pic32mx_phyread(phyaddr, MII_MCR)); + dbg(" MSR: %04x\n", pic32mx_phyread(phyaddr, MII_MSR)); + dbg(" ADVERTISE: %04x\n", pic32mx_phyread(phyaddr, MII_ADVERTISE)); + dbg(" LPA: %04x\n", pic32mx_phyread(phyaddr, MII_LPA)); + dbg(" EXPANSION: %04x\n", pic32mx_phyread(phyaddr, MII_EXPANSION)); +#ifdef CONFIG_PHY_KS8721 + dbg(" 10BTCR: %04x\n", pic32mx_phyread(phyaddr, MII_KS8721_10BTCR)); +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mx_phywrite + * + * Description: + * Write a value to an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * phydata - The data to write to the PHY register + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static void pic32mx_phywrite(uint8_t phyaddr, uint8_t regaddr, uint16_t phydata) +{ + uint32_t regval; + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mx_putreg(regval, PIC32MX_EMAC1_MADR); + + /* Set up to write */ + + pic32mx_putreg(EMAC1_MCMD_WRITE, PIC32MX_EMAC1_MCMD); + + /* Write the register data to the PHY */ + + pic32mx_putreg((uint32_t)phydata, PIC32MX_EMAC1_MWTD); + + /* Wait for the PHY command to complete */ + + while ((pic32mx_getreg(PIC32MX_EMAC1_MIND) & EMAC1_MIND_MIIMBUSY) != 0); +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyread + * + * Description: + * Read a value from an MII PHY register + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * regaddr - The address of the PHY register to be written + * + * Returned Value: + * Data read from the PHY register + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static uint16_t pic32mx_phyread(uint8_t phyaddr, uint8_t regaddr) +{ + uint32_t regval; + + pic32mx_putreg(0, PIC32MX_EMAC1_MCMD); + + /* Set PHY address and PHY register address */ + + regval = ((uint32_t)phyaddr << EMAC1_MADR_PHYADDR_SHIFT) | + ((uint32_t)regaddr << EMAC1_MADR_REGADDR_SHIFT); + pic32mx_putreg(regval, PIC32MX_EMAC1_MADR); + + /* Set up to read */ + + pic32mx_putreg(EMAC1_MCMD_READ, PIC32MX_EMAC1_MCMD); + + /* Wait for the PHY command to complete */ + + while ((pic32mx_getreg(PIC32MX_EMAC1_MIND) & (EMAC1_MIND_MIIMBUSY|EMAC1_MIND_NOTVALID)) != 0); + pic32mx_putreg(0, PIC32MX_EMAC1_MCMD); + + /* Return the PHY register data */ + + return (uint16_t)(pic32mx_getreg(PIC32MX_EMAC1_MRDD) & EMAC1_MRDD_MASK); +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyreset + * + * Description: + * Reset the PHY + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static inline int pic32mx_phyreset(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Reset the PHY. Needs a minimal 50uS delay after reset. */ + + pic32mx_phywrite(phyaddr, MII_MCR, MII_MCR_RESET); + + /* Wait for a minimum of 50uS no matter what */ + + up_udelay(50); + + /* The MCR reset bit is self-clearing. Wait for it to be clear indicating + * that the reset is complete. + */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { + phyreg = pic32mx_phyread(phyaddr, MII_MCR); + if ((phyreg & MII_MCR_RESET) == 0) + { + return OK; + } + } + + ndbg("Reset failed. MCR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyautoneg + * + * Description: + * Enable auto-negotiation. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * + * Returned Value: + * None + * + * Assumptions: + * The adverisement regiser has already been configured. + * + ****************************************************************************/ + +#if defined(PIC32MX_HAVE_PHY) && defined(CONFIG_PHY_AUTONEG) +static inline int pic32mx_phyautoneg(uint8_t phyaddr) +{ + int32_t timeout; + uint16_t phyreg; + + /* Start auto-negotiation */ + + pic32mx_phywrite(phyaddr, MII_MCR, MII_MCR_ANENABLE | MII_MCR_ANRESTART); + + /* Wait for autonegotiation to complete */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { + /* Check if auto-negotiation has completed */ + + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_ANEGCOMPLETE) != 0) + { + /* Yes.. return success */ + + return OK; + } + } + + ndbg("Auto-negotiation failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phymode + * + * Description: + * Set the PHY to operate at a selected speed/duplex mode. + * + * Parameters: + * phyaddr - The device address where the PHY was discovered + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static int pic32mx_phymode(uint8_t phyaddr, uint8_t mode) +{ + int32_t timeout; + uint16_t phyreg; + + /* Disable auto-negotiation and set fixed Speed and Duplex settings: + * + * MII_MCR_UNIDIR 0=Disable unidirectional enable + * MII_MCR_SPEED1000 0=Reserved on 10/100 + * MII_MCR_CTST 0=Disable collision test + * MII_MCR_FULLDPLX ?=Full duplex + * MII_MCR_ANRESTART 0=Don't restart auto negotiation + * MII_MCR_ISOLATE 0=Don't electronically isolate PHY from MII + * MII_MCR_PDOWN 0=Don't powerdown the PHY + * MII_MCR_ANENABLE 0=Disable auto negotiation + * MII_MCR_SPEED100 ?=Select 100Mbps + * MII_MCR_LOOPBACK 0=Disable loopback mode + * MII_MCR_RESET 0=No PHY reset + */ + + phyreg = 0; + if ((mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100) + { + phyreg = MII_MCR_SPEED100; + } + + if ((mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL) + { + phyreg |= MII_MCR_FULLDPLX; + } + + pic32mx_phywrite(phyaddr, MII_MCR, phyreg); + + /* Then wait for the link to be established */ + + for (timeout = MII_BIG_TIMEOUT; timeout > 0; timeout--) + { +#ifdef CONFIG_PHY_DP83848C + phyreg = pic32mx_phyread(phyaddr, MII_DP83848C_STS); + if ((phyreg & 0x0001) != 0) + { + /* Yes.. return success */ + + return OK; + } +#else + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_LINKSTATUS) != 0) + { + /* Yes.. return success */ + + return OK; + } +#endif + } + + ndbg("Link failed. MSR: %04x\n", phyreg); + return -ETIMEDOUT; +} +#endif + +/**************************************************************************** + * Function: pic32mx_phyinit + * + * Description: + * Initialize the PHY + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directly. As a side-effect, it will initialize priv->pd_phyaddr + * and priv->pd_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv) +{ + unsigned int phyaddr; + uint16_t phyreg; + uint32_t regval; + int ret; + + /* MII configuration: host clocked divided per board.h, no suppress + * preamble, no scan increment. + */ + + pic32mx_putreg(EMAC1_MCFG_CLKSEL_DIV, PIC32MX_EMAC1_MCFG); + pic32mx_putreg(0, PIC32MX_EMAC1_MCMD); + + /* Enter RMII mode and select 100 MBPS support */ + + pic32mx_putreg(ETH_CMD_RMII, PIC32MX_ETH_CMD); + pic32mx_putreg(EMAC1_SUPP_SPEEDRMII:, PIC32MX_ETH_SUPP); + + /* Find PHY Address. Because the controller has a pull-up and the + * PHY has pull-down resistors on RXD lines some times the PHY + * latches different at different addresses. + */ + + for (phyaddr = 1; phyaddr < 32; phyaddr++) + { + /* Check if we can see the selected device ID at this + * PHY address. + */ + + phyreg = (unsigned int)pic32mx_phyread(phyaddr, MII_PHYID1); + nvdbg("Addr: %d PHY ID1: %04x\n", phyaddr, phyreg); + + if (phyreg == PIC32MX_PHYID1) + { + phyreg = pic32mx_phyread(phyaddr, MII_PHYID2); + nvdbg("Addr: %d PHY ID2: %04x\n", phyaddr, phyreg); + + if (phyreg == PIC32MX_PHYID2) + { + break; + } + } + } + + /* Check if the PHY device address was found */ + + if (phyaddr > 31) + { + /* Failed to find PHY at any location */ + + ndbg("No PHY detected\n"); + return -ENODEV; + } + nvdbg("phyaddr: %d\n", phyaddr); + + /* Save the discovered PHY device address */ + + priv->pd_phyaddr = phyaddr; + + /* Reset the PHY */ + + ret = pic32mx_phyreset(phyaddr); + if (ret < 0) + { + return ret; + } + pic32mx_showmii(phyaddr, "After reset"); + + /* Check for preamble suppression support */ + + phyreg = pic32mx_phyread(phyaddr, MII_MSR); + if ((phyreg & MII_MSR_MFRAMESUPPRESS) != 0) + { + /* The PHY supports preamble suppression */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_MCFG); + regval |= EMAC1_MCFG_NOPRE; + pic32mx_putreg(regval, PIC32MX_EMAC1_MCFG); + } + + /* Are we configured to do auto-negotiation? */ + +#ifdef CONFIG_PHY_AUTONEG + /* Setup the Auto-negotiation advertisement: 100 or 10, and HD or FD */ + + pic32mx_phywrite(phyaddr, MII_ADVERTISE, + (MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF | + MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF | + MII_ADVERTISE_CSMA)); + + /* Then perform the auto-negotiation */ + + ret = pic32mx_phyautoneg(phyaddr); + if (ret < 0) + { + return ret; + } +#else + /* Set up the fixed PHY configuration */ + + ret = pic32mx_phymode(phyaddr, PIC32MX_MODE_DEFLT); + if (ret < 0) + { + return ret; + } +#endif + + /* The link is established */ + + pic32mx_showmii(phyaddr, "After link established"); + + /* Check configuration */ + +#if defined(CONFIG_PHY_KS8721) + phyreg = pic32mx_phyread(phyaddr, MII_KS8721_10BTCR); + + switch (phyreg & KS8721_10BTCR_MODE_MASK) + { + case KS8721_10BTCR_MODE_10BTHD: /* 10BASE-T half duplex */ + priv->pd_mode = PIC32MX_10BASET_HD; + pic32mx_putreg(0, PIC32MX_ETH_SUPP); + break; + case KS8721_10BTCR_MODE_100BTHD: /* 100BASE-T half duplex */ + priv->pd_mode = PIC32MX_100BASET_HD; + break; + case KS8721_10BTCR_MODE_10BTFD: /* 10BASE-T full duplex */ + priv->pd_mode = PIC32MX_10BASET_FD; + pic32mx_putreg(0, PIC32MX_ETH_SUPP); + break; + case KS8721_10BTCR_MODE_100BTFD: /* 100BASE-T full duplex */ + priv->pd_mode = PIC32MX_100BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_PHY_DP83848C) + phyreg = pic32mx_phyread(phyaddr, MII_DP83848C_STS); + + /* Configure for full/half duplex mode and speed */ + + switch (phyreg & 0x0006) + { + case 0x0000: + priv->pd_mode = PIC32MX_100BASET_HD; + break; + case 0x0002: + priv->pd_mode = PIC32MX_10BASET_HD; + break; + case 0x0004: + priv->pd_mode = PIC32MX_100BASET_FD; + break; + case 0x0006: + priv->pd_mode = PIC32MX_10BASET_FD; + break; + default: + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } +#elif defined(CONFIG_PHY_LAN8720) + { + uint16_t advertise; + uint16_t lpa; + + up_udelay(500); + advertise = pic32mx_phyread(phyaddr, MII_ADVERTISE); + lpa = pic32mx_phyread(phyaddr, MII_LPA); + + /* Check for 100BASETX full duplex */ + + if ((advertise & MII_ADVERTISE_100BASETXFULL) != 0 && + (lpa & MII_LPA_100BASETXFULL) != 0) + { + priv->pd_mode = PIC32MX_100BASET_FD; + } + + /* Check for 100BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_100BASETXHALF) != 0 && + (lpa & MII_LPA_100BASETXHALF) != 0) + { + priv->pd_mode = PIC32MX_100BASET_HD; + } + + /* Check for 10BASETX full duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXFULL) != 0 && + (lpa & MII_LPA_10BASETXFULL) != 0) + { + priv->pd_mode = PIC32MX_10BASET_FD; + } + + /* Check for 10BASETX half duplex */ + + else if ((advertise & MII_ADVERTISE_10BASETXHALF) != 0 && + (lpa & MII_LPA_10BASETXHALF) != 0) + { + priv->pd_mode = PIC32MX_10BASET_HD; + } + else + { + ndbg("Unrecognized mode: %04x\n", phyreg); + return -ENODEV; + } + } +#else +# warning "PHY Unknown: speed and duplex are bogus" +#endif + + ndbg("%dBase-T %s duplex\n", + (priv->pd_mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100 ? 100 : 10, + (priv->pd_mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL ?"full" : "half"); + + /* Disable auto-configuration. Set the fixed speed/duplex mode. + * (probably more than little redundant). + */ + + ret = pic32mx_phymode(phyaddr, priv->pd_mode); + pic32mx_showmii(phyaddr, "After final configuration"); + return ret; +} +#else +static inline int pic32mx_phyinit(struct pic32mx_driver_s *priv) +{ + priv->pd_mode = PIC32MX_MODE_DEFLT; + return OK; +} +#endif + +/**************************************************************************** + * Function: pic32mx_txdescinit + * + * Description: + * Initialize the EMAC Tx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directory. + * As a side-effect, it will initialize priv->pd_phyaddr and + * priv->pd_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mx_txdescinit(struct pic32mx_driver_s *priv) +{ + uint32_t *txdesc; + uint32_t *txstat; + uint32_t pktaddr; + int i; + + /* Configure Tx descriptor and status tables */ + + pic32mx_putreg(PIC32MX_TXDESC_BASE, PIC32MX_ETH_TXDESC); + pic32mx_putreg(PIC32MX_TXSTAT_BASE, PIC32MX_ETH_TXSTAT); + pic32mx_putreg(CONFIG_NET_NTXDESC-1, PIC32MX_ETH_TXDESCRNO); + + /* Initialize Tx descriptors and link to packet buffers */ + + txdesc = (uint32_t*)PIC32MX_TXDESC_BASE; + pktaddr = PIC32MX_TXBUFFER_BASE; + + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + *txdesc++ = pktaddr; + *txdesc++ = (TXDESC_CONTROL_INT | (PIC32MX_MAXPACKET_SIZE - 1)); + pktaddr += PIC32MX_MAXPACKET_SIZE; + } + + /* Initialize Tx status */ + + txstat = (uint32_t*)PIC32MX_TXSTAT_BASE; + for (i = 0; i < CONFIG_NET_NTXDESC; i++) + { + *txstat++ = 0; + } + + /* Point to first Tx descriptor */ + + pic32mx_putreg(0, PIC32MX_ETH_TXPRODIDX); +} + +/**************************************************************************** + * Function: pic32mx_rxdescinit + * + * Description: + * Initialize the EMAC Rx descriptor table + * + * Parameters: + * priv - Pointer to EMAC device driver structure + * + * Returned Value: + * None directory. + * As a side-effect, it will initialize priv->pd_phyaddr and + * priv->pd_phymode. + * + * Assumptions: + * + ****************************************************************************/ + +static inline void pic32mx_rxdescinit(struct pic32mx_driver_s *priv) +{ + uint32_t *rxdesc; + uint32_t *rxstat; + uint32_t pktaddr; + int i; + + /* Configure Rx descriptor and status tables */ + + pic32mx_putreg(PIC32MX_RXDESC_BASE, PIC32MX_ETH_RXDESC); + pic32mx_putreg(PIC32MX_RXSTAT_BASE, PIC32MX_ETH_RXSTAT); + pic32mx_putreg(CONFIG_NET_NRXDESC-1, PIC32MX_ETH_RXDESCNO); + + /* Initialize Rx descriptors and link to packet buffers */ + + rxdesc = (uint32_t*)PIC32MX_RXDESC_BASE; + pktaddr = PIC32MX_RXBUFFER_BASE; + + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + *rxdesc++ = pktaddr; + *rxdesc++ = (RXDESC_CONTROL_INT | (PIC32MX_MAXPACKET_SIZE - 1)); + pktaddr += PIC32MX_MAXPACKET_SIZE; + } + + /* Initialize Rx status */ + + rxstat = (uint32_t*)PIC32MX_RXSTAT_BASE; + for (i = 0; i < CONFIG_NET_NRXDESC; i++) + { + *rxstat++ = 0; + *rxstat++ = 0; + } + + /* Point to first Rx descriptor */ + + pic32mx_putreg(0, PIC32MX_ETH_RXCONSIDX); +} + +/**************************************************************************** + * Function: pic32mx_macmode + * + * Description: + * Set the MAC to operate at a selected speed/duplex mode. + * + * Parameters: + * mode - speed/duplex mode + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef PIC32MX_HAVE_PHY +static void pic32mx_macmode(uint8_t mode) +{ + uint32_t regval; + + /* Set up for full or half duplex operation */ + + if ((mode & PIC32MX_DUPLEX_MASK) == PIC32MX_DUPLEX_FULL) + { + /* Set the back-to-back inter-packet gap */ + + pic32mx_putreg(21, PIC32MX_EMAC1_IPGT); + + /* Set MAC to operate in full duplex mode with CRC and Pad enabled */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_CFG2); + regval |= (EMAC1_CFG2_FULLDPLX | EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN); + pic32mx_putreg(regval, PIC32MX_EMAC1_CFG2); + + /* Select full duplex operation for ethernet controller */ + + regval = pic32mx_getreg(PIC32MX_ETH_CMD); + regval |= (ETH_CMD_FD | ETH_CMD_RMII | ETH_CMD_PRFRAME); + pic32mx_putreg(regval, PIC32MX_ETH_CMD); + } + else + { + /* Set the back-to-back inter-packet gap */ + + pic32mx_putreg(18, PIC32MX_EMAC1_IPGT); + + /* Set MAC to operate in half duplex mode with CRC and Pad enabled */ + + regval = pic32mx_getreg(PIC32MX_EMAC1_CFG2); + regval &= ~EMAC1_CFG2_FULLDPLX; + regval |= (EMAC1_CFG2_CRCEN | EMAC1_CFG2_PADCRCEN); + pic32mx_putreg(regval, PIC32MX_EMAC1_CFG2); + + /* Select half duplex operation for ethernet controller */ + + regval = pic32mx_getreg(PIC32MX_ETH_CMD); + regval &= ~ETH_CMD_FD; + regval |= (ETH_CMD_RMII | ETH_CMD_PRFRAME); + pic32mx_putreg(regval, PIC32MX_ETH_CMD); + } + + /* This is currently done in pic32mx_phyinit(). That doesn't + * seem like the right place. It should be done here. + */ + +#if 0 + regval = pic32mx_getreg(PIC32MX_ETH_SUPP); + if ((mode & PIC32MX_SPEED_MASK) == PIC32MX_SPEED_100) + { + regval |= EMAC1_SUPP_SPEEDRMII:; + } + else + { + regval &= ~EMAC1_SUPP_SPEEDRMII:; + } + pic32mx_putreg(regval, PIC32MX_ETH_SUPP); +#endif +} +#endif + +/**************************************************************************** + * Function: pic32mx_ethreset + * + * Description: + * Configure and reset the Ethernet module, leaving it in a disabled state. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * + ****************************************************************************/ + +static void pic32mx_ethreset(struct pic32mx_driver_s *priv) +{ + irqstate_t flags; + + /* Reset the MAC */ + + flags = irqsave(); + + /* Put the MAC into the reset state */ + + pic32mx_putreg((EMAC1_CFG1_TXRST | EMAC1_CFG1_MCSTXRST | EMAC1_CFG1_RXRST | + EMAC1_CFG1_MCSRXRST | EMAC1_CFG1_SIMRST | EMAC1_CFG1_SOFTRST), + PIC32MX_EMAC1_CFG1); + + /* Disable RX/RX, clear modes, reset all control registers */ + + pic32mx_putreg((ETH_CMD_REGRST | ETH_CMD_TXRST | ETH_CMD_RXRST), + PIC32MX_ETH_CMD); + + /* Take the MAC out of the reset state */ + + up_udelay(50); + pic32mx_putreg(0, PIC32MX_EMAC1_CFG1); + + /* The RMII bit must be set on initialization (I'm not sure this needs + * to be done here but... oh well). + */ + + pic32mx_putreg(ETH_CMD_RMII, PIC32MX_ETH_CMD); + + /* Set other misc configuration-related registers to default values */ + + pic32mx_putreg(0, PIC32MX_EMAC1_CFG2); + pic32mx_putreg(0, PIC32MX_ETH_SUPP); + pic32mx_putreg(0, PIC32MX_EMAC1_TEST); + + pic32mx_putreg(((12 << EMAC1_IPGR_GAP1_SHIFT) | (12 << EMAC1_IPGR_GAP2_SHIFT)), + PIC32MX_EMAC1_IPGR); + pic32mx_putreg(((15 << EMAC1_CLRT_RETX_SHIFT) | (55 << EMAC1_CLRT_CWINDOW_SHIFT)), + PIC32MX_EMAC1_CLRT); + + /* Set the Maximum Frame size register. "This field resets to the value + * 0x0600, which represents a maximum receive frame of 1536 octets. An + * untagged maximum size Ethernet frame is 1518 octets. A tagged frame adds + * four octets for a total of 1522 octets. If a shorter maximum length + * restriction is desired, program this 16-bit field." + */ + + pic32mx_putreg(PIC32MX_MAXPACKET_SIZE, PIC32MX_EMAC1_MAXF); + + /* Disable all Ethernet controller interrupts */ + + pic32mx_putreg(0, PIC32MX_ETH_INTEN); + + /* Clear any pending interrupts (shouldn't be any) */ + + pic32mx_putreg(0xffffffff, PIC32MX_ETH_INTCLR); + irqrestore(flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pic32mx_ethinitialize + * + * Description: + * Initialize one Ethernet controller and driver structure. + * + * Parameters: + * intf - Selects the interface to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +int pic32mx_ethinitialize(int intf) +#else +static inline int pic32mx_ethinitialize(int intf) +#endif +{ + struct pic32mx_driver_s *priv; + uint32_t regval; + int ret; + int i; + + DEBUGASSERT(intf < CONFIG_PIC32MX_NINTERFACES); + priv = &g_ethdrvr[intf]; + + /* Turn on the ethernet MAC clock */ + + regval = pic32mx_getreg(PIC32MX_SYSCON_PCONP); + regval |= SYSCON_PCONP_PCENET; + pic32mx_putreg(regval, PIC32MX_SYSCON_PCONP); + + /* Configure all GPIO pins needed by ENET */ + + for (i = 0; i < GPIO_NENET_PINS; i++) + { + (void)pic32mx_configgpio(g_enetpins[i]); + } + pic32mx_showpins(); + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct pic32mx_driver_s)); + priv->pd_dev.d_ifup = pic32mx_ifup; /* I/F down callback */ + priv->pd_dev.d_ifdown = pic32mx_ifdown; /* I/F up (new IP address) callback */ + priv->pd_dev.d_txavail = pic32mx_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->pd_dev.d_addmac = pic32mx_addmac; /* Add multicast MAC address */ + priv->pd_dev.d_rmmac = pic32mx_rmmac; /* Remove multicast MAC address */ +#endif + priv->pd_dev.d_private = (void*)priv; /* Used to recover private state from dev */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 +# error "A mechanism to associate base address an IRQ with an interface is needed" + priv->pd_base = ??; /* Ethernet controller base address */ + priv->pd_irq = ??; /* Ethernet controller IRQ vector number */ + priv->pd_irqsrc = ??; /* Ethernet controller IRQ source number */ +#endif + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->pd_txpoll = wd_create(); /* Create periodic poll timer */ + priv->pd_txtimeout = wd_create(); /* Create TX timeout timer */ + + /* Reset the Ethernet controller and leave in the ifdown statue. The + * Ethernet controller will be properly re-initialized each time + * pic32mx_ifup() is called. + */ + + pic32mx_ifdown(&priv->pd_dev); + + /* Attach the IRQ to the driver */ + +#if CONFIG_PIC32MX_NINTERFACES > 1 + ret = irq_attach(priv->pd_irq, pic32mx_interrupt); +#else + ret = irq_attach(PIC32MX_IRQ_ETH, pic32mx_interrupt); +#endif + if (ret != 0) + { + /* We could not attach the ISR to the the interrupt */ + + return -EAGAIN; + } + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->pd_dev); + return OK; +} + +/**************************************************************************** + * Name: up_netinitialize + * + * Description: + * Initialize the first network interface. If there are more than one + * interface in the chip, then board-specific logic will have to provide + * this function to determine which, if any, Ethernet controllers should + * be initialized. + * + ****************************************************************************/ + +#if CONFIG_PIC32MX_NINTERFACES == 1 +void up_netinitialize(void) +{ + (void)pic32mx_ethinitialize(0); +} +#endif +#endif /* CHIP_NETHERNET > 0 */ +#endif /* CONFIG_NET && CONFIG_PIC32MX_ETHERNET */ diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.h b/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.h index 9df46f21b..0816f2091 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-ethernet.h @@ -1,89 +1,633 @@ -/****************************************************************************
- * arch/mips/src/pic32mx/pic32mx-ethernet.h
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name NuttX 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.
- *
- ****************************************************************************/
-
-#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H
-#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include "pic32mx-memorymap.h"
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-/* Register Offsets *********************************************************/
-
-#warning "To be provided"
-
-/* Register Addresses *******************************************************/
-
-#warning "To be provided"
-
-/* Register Bit-Field Definitions *******************************************/
-
-#warning "To be provided"
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-#ifndef __ASSEMBLY__
-
-/****************************************************************************
- * Inline Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H */
+/******************************************************************************************** + * arch/mips/src/pic32mx/pic32mx-ethernet.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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. + * + ********************************************************************************************/ + +#ifndef __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H +#define __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include <nuttx/config.h> + +#include "pic32mx-memorymap.h" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ +/* Register Offsets *************************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MX_ETH_CON1_OFFSET 0x0000 /* Ethernet Controller Control 1 Register */ +#define PIC32MX_ETH_CON1SET_OFFSET 0x0004 +#define PIC32MX_ETH_CON1CLR_OFFSET 0x0008 +#define PIC32MX_ETH_CON1INV_OFFSET 0x000c +#define PIC32MX_ETH_CON2_OFFSET 0x0010 /* Ethernet Controller Control 2 Register */ +#define PIC32MX_ETH_CON2SET_OFFSET 0x0014 +#define PIC32MX_ETH_CON2CLR_OFFSET 0x0018 +#define PIC32MX_ETH_CON2INV_OFFSET 0x001c +#define PIC32MX_ETH_TXST_OFFSET 0x0020 /* Ethernet Controller TX Packet Descriptor Start Address Register */ +#define PIC32MX_ETH_TXSTSET_OFFSET 0x0024 +#define PIC32MX_ETH_TXSTCLR_OFFSET 0x0028 +#define PIC32MX_ETH_TXSTINV_OFFSET 0x002c +#define PIC32MX_ETH_RXST_OFFSET 0x0030 /* Ethernet Controller RX Packet Descriptor Start Address Register */ +#define PIC32MX_ETH_RXSTSET_OFFSET 0x0034 +#define PIC32MX_ETH_RXSTCLR_OFFSET 0x0038 +#define PIC32MX_ETH_RXSTINV_OFFSET 0x003c + +#define PIC32MX_ETH_IEN_OFFSET 0x00c0 /* Ethernet Controller Interrupt Enable Register */ +#define PIC32MX_ETH_IENSET_OFFSET 0x00c4 +#define PIC32MX_ETH_IENCLR_OFFSET 0x00c8 +#define PIC32MX_ETH_IENINV_OFFSET 0x00cc +#define PIC32MX_ETH_IRQ_OFFSET 0x00d0 /* Ethernet Controller Interrupt Request Register */ +#define PIC32MX_ETH_IENSET_OFFSET 0x00d4 +#define PIC32MX_ETH_IENCLR_OFFSET 0x00d8 +#define PIC32MX_ETH_IENINV_OFFSET 0x00dc +#define PIC32MX_ETH_STAT_OFFSET 0x00e0 /* Ethernet Controller Status Register */ + +/* RX Filtering Configuration Registers */ + +#define PIC32MX_ETH_RXFC_OFFSET 0x00a0 /* Ethernet Controller Receive Filter Configuration Register */ +#define PIC32MX_ETH_RXFCSET_OFFSET 0x00a4 +#define PIC32MX_ETH_RXFCCLR_OFFSET 0x00a8 +#define PIC32MX_ETH_RXFCINV_OFFSET 0x00ac + +#define PIC32MX_ETH_HT0_OFFSET 0x0040 /* Ethernet Controller Hash Table 0 Register */ +#define PIC32MX_ETH_HT0SET_OFFSET 0x0044 +#define PIC32MX_ETH_HT0CLR_OFFSET 0x0048 +#define PIC32MX_ETH_HT0INV_OFFSET 0x004c +#define PIC32MX_ETH_HT1_OFFSET 0x0050 /* Ethernet Controller Hash Table 1 Register */ +#define PIC32MX_ETH_HT1SET_OFFSET 0x0054 +#define PIC32MX_ETH_HT1CLR_OFFSET 0x0058 +#define PIC32MX_ETH_HT1INV_OFFSET 0x005c +#define PIC32MX_ETH_PMM0_OFFSET 0x0060 /* Ethernet Controller Pattern Match Mask 0 Register */ +#define PIC32MX_ETH_PMM0SET_OFFSET 0x0064 +#define PIC32MX_ETH_PMM0CLR_OFFSET 0x0068 +#define PIC32MX_ETH_PMM0INV_OFFSET 0x006c +#define PIC32MX_ETH_PMM1_OFFSET 0x0070 /* Ethernet Controller Pattern Match Mask 1 Register */ +#define PIC32MX_ETH_PMM1SET_OFFSET 0x0074 +#define PIC32MX_ETH_PMM1CLR_OFFSET 0x0078 +#define PIC32MX_ETH_PMM1INV_OFFSET 0x007c +#define PIC32MX_ETH_PMCS_OFFSET 0x0080 /* Ethernet Controller Pattern Match Checksum Register */ +#define PIC32MX_ETH_PMCSSET_OFFSET 0x0084 +#define PIC32MX_ETH_PMCSCLR_OFFSET 0x0088 +#define PIC32MX_ETH_PMCSINV_OFFSET 0x008c +#define PIC32MX_ETH_PMO_OFFSET 0x0090 /* Ethernet Controller Pattern Match Offset Register */ +#define PIC32MX_ETH_PMOSET_OFFSET 0x0094 +#define PIC32MX_ETH_PMOCLR_OFFSET 0x0098 +#define PIC32MX_ETH_PMOINV_OFFSET 0x009c + +/* Flow Control Configuring Register */ + +#define PIC32MX_ETH_RXWM_OFFSET 0x00b0 /* Ethernet Controller Receive Watermarks Register */ +#define PIC32MX_ETH_RXWMSET_OFFSET 0x00b4 +#define PIC32MX_ETH_RXWMCLR_OFFSET 0x00b8 +#define PIC32MX_ETH_RXWMINV_OFFSET 0x00bc + +/* Ethernet Statistics Registers */ + +#define PIC32MX_ETH_RXOVFLOW_OFFSET 0x0100 /* Ethernet Controller Receive Overflow Statistics Register */ +#define PIC32MX_ETH_RXOVFLOWSET_OFFSET 0x0104 +#define PIC32MX_ETH_RXOVFLOWCLR_OFFSET 0x0108 +#define PIC32MX_ETH_RXOVFLOWINV_OFFSET 0x010c +#define PIC32MX_ETH_FRMTXOK_OFFSET 0x0110 /* Ethernet Controller Frames Transmitted OK Statistics Register */ +#define PIC32MX_ETH_FRMTXOKSET_OFFSET 0x0114 +#define PIC32MX_ETH_FRMTXOKCLR_OFFSET 0x0118 +#define PIC32MX_ETH_FRMTXOKINV_OFFSET 0x011c +#define PIC32MX_ETH_SCOLFRM_OFFSET 0x0120 /* Ethernet Controller Single Collision Frames Statistics Register */ +#define PIC32MX_ETH_SCOLFRMSET_OFFSET 0x0124 +#define PIC32MX_ETH_SCOLFRMCLR_OFFSET 0x0128 +#define PIC32MX_ETH_SCOLFRMINV_OFFSET 0x012c +#define PIC32MX_ETH_MCOLFRM_OFFSET 0x0130 /* Ethernet Controller Multiple Collision Frames Statistics Register */ +#define PIC32MX_ETH_MCOLFRMSET_OFFSET 0x0134 +#define PIC32MX_ETH_MCOLFRMCLR_OFFSET 0x0138 +#define PIC32MX_ETH_MCOLFRMINV_OFFSET 0x013c +#define PIC32MX_ETH_FRMRXOK_OFFSET 0x0140 /* Ethernet Controller Frames Received OK Statistics Register */ +#define PIC32MX_ETH_FRMRXOKSET_OFFSET 0x0144 +#define PIC32MX_ETH_FRMRXOKCLR_OFFSET 0x0148 +#define PIC32MX_ETH_FRMRXOKINV_OFFSET 0x014c +#define PIC32MX_ETH_FCSERR_OFFSET 0x0150 /* Ethernet Controller Frame Check Sequence Error Statistics Register */ +#define PIC32MX_ETH_FCSERRSET_OFFSET 0x0154 +#define PIC32MX_ETH_FCSERRCLR_OFFSET 0x0158 +#define PIC32MX_ETH_FCSERRINV_OFFSET 0x015c +#define PIC32MX_ETH_ALGNERR_OFFSET 0x0160 /* Ethernet Controller Alignment Errors Statistics Register */ +#define PIC32MX_ETH_ALGNERRSET_OFFSET 0x0164 +#define PIC32MX_ETH_ALGNERRCLR_OFFSET 0x0168 +#define PIC32MX_ETH_ALGNERRINV_OFFSET 0x016c + +/* MAC Configuration Registers */ + +#define PIC32MX_EMAC1_CFG1_OFFSET 0x0200 /* Ethernet Controller MAC Configuration 1 Register */ +#define PIC32MX_EMAC1_CFG1SET_OFFSET 0x0204 +#define PIC32MX_EMAC1_CFG1CLR_OFFSET 0x0208 +#define PIC32MX_EMAC1_CFG1INV_OFFSET 0x020c +#define PIC32MX_EMAC1_CFG2_OFFSET 0x0210 /* Ethernet Controller MAC Configuration 2 Register */ +#define PIC32MX_EMAC1_CFG2SET_OFFSET 0x0214 +#define PIC32MX_EMAC1_CFG2CLR_OFFSET 0x0218 +#define PIC32MX_EMAC1_CFG2INV_OFFSET 0x021c +#define PIC32MX_EMAC1_IPGT_OFFSET 0x0220 /* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ +#define PIC32MX_EMAC1_IPGTSET_OFFSET 0x0224 +#define PIC32MX_EMAC1_IPGTCLR_OFFSET 0x0228 +#define PIC32MX_EMAC1_IPGTINV_OFFSET 0x022c +#define PIC32MX_EMAC1_IPGR_OFFSET 0x0230 /* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ +#define PIC32MX_EMAC1_IPGRSET_OFFSET 0x0234 +#define PIC32MX_EMAC1_IPGRCLR_OFFSET 0x0238 +#define PIC32MX_EMAC1_IPGRINV_OFFSET 0x023c +#define PIC32MX_EMAC1_CLRT_OFFSET 0x0240 /* Ethernet Controller MAC Collision Window/Retry Limit Register */ +#define PIC32MX_EMAC1_CLRTSET_OFFSET 0x0244 +#define PIC32MX_EMAC1_CLRTCLR_OFFSET 0x0248 +#define PIC32MX_EMAC1_CLRTINV_OFFSET 0x024c +#define PIC32MX_EMAC1_MAXF_OFFSET 0x0250 /* Ethernet Controller MAC Maximum Frame Length Register */ +#define PIC32MX_EMAC1_MAXFSET_OFFSET 0x0254 +#define PIC32MX_EMAC1_MAXFCLR_OFFSET 0x0258 +#define PIC32MX_EMAC1_MAXFINV_OFFSET 0x025c +#define PIC32MX_EMAC1_SUPP_OFFSET 0x0260 /* Ethernet Controller MAC PHY Support Register */ +#define PIC32MX_EMAC1_SUPPSET_OFFSET 0x0264 +#define PIC32MX_EMAC1_SUPPCLR_OFFSET 0x0268 +#define PIC32MX_EMAC1_SUPPINV_OFFSET 0x026c +#define PIC32MX_EMAC1_TEST_OFFSET 0x0270 /* Ethernet Controller MAC Test Register */ +#define PIC32MX_EMAC1_TESTSET_OFFSET 0x0274 +#define PIC32MX_EMAC1_TESTCLR_OFFSET 0x0278 +#define PIC32MX_EMAC1_TESTINV_OFFSET 0x027c + +#define PIC32MX_EMAC1_SA0_OFFSET 0x0300 /* Ethernet Controller MAC Station Address 0 Register */ +#define PIC32MX_EMAC1_SA0SET_OFFSET 0x0304 +#define PIC32MX_EMAC1_SA0CLR_OFFSET 0x0308 +#define PIC32MX_EMAC1_SA0INV_OFFSET 0x030c +#define PIC32MX_EMAC1_SA1_OFFSET 0x0310 /* Ethernet Controller MAC Station Address 1 Register */ +#define PIC32MX_EMAC1_SA1SET_OFFSET 0x0314 +#define PIC32MX_EMAC1_SA1CLR_OFFSET 0x0318 +#define PIC32MX_EMAC1_SA1INV_OFFSET 0x031c +#define PIC32MX_EMAC1_SA2_OFFSET 0x0320 /* Ethernet Controller MAC Station Address 2 Register */ +#define PIC32MX_EMAC1_SA2SET_OFFSET 0x0324 +#define PIC32MX_EMAC1_SA2CLR_OFFSET 0x0328 +#define PIC32MX_EMAC1_SA2INV_OFFSET 0x032c + +/* MII Management Registers */ + +#define PIC32MX_EMAC1_MCFG_OFFSET 0x0280 /* Ethernet Controller MAC MII Management Configuration Register */ +#define PIC32MX_EMAC1_MCFGSET_OFFSET 0x0284 +#define PIC32MX_EMAC1_MCFGCLR_OFFSET 0x0288 +#define PIC32MX_EMAC1_MCFGINV_OFFSET 0x028c +#define PIC32MX_EMAC1_MCMD_OFFSET 0x0290 /* Ethernet Controller MAC MII Management Command Register */ +#define PIC32MX_EMAC1_MCMDSET_OFFSET 0x0294 +#define PIC32MX_EMAC1_MCMDCLR_OFFSET 0x0298 +#define PIC32MX_EMAC1_MCMDINV_OFFSET 0x029c +#define PIC32MX_EMAC1_MADR_OFFSET 0x02a0 /* Ethernet Controller MAC MII Management Address Register */ +#define PIC32MX_EMAC1_MADRSET_OFFSET 0x02a4 +#define PIC32MX_EMAC1_MADRCLR_OFFSET 0x02a8 +#define PIC32MX_EMAC1_MADRINV_OFFSET 0x02ac +#define PIC32MX_EMAC1_MWTD_OFFSET 0x02b0 /* Ethernet Controller MAC MII Management Write Data Register */ +#define PIC32MX_EMAC1_MWTDSET_OFFSET 0x02b4 +#define PIC32MX_EMAC1_MWTDCLR_OFFSET 0x02b8 +#define PIC32MX_EMAC1_MWTDINV_OFFSET 0x02bc +#define PIC32MX_EMAC1_MRDD_OFFSET 0x02c0 /* Ethernet Controller MAC MII Management Read Data Register */ +#define PIC32MX_EMAC1_MRDDSET_OFFSET 0x02c4 +#define PIC32MX_EMAC1_MRDDCLR_OFFSET 0x02c8 +#define PIC32MX_EMAC1_MRDDINV_OFFSET 0x02cc +#define PIC32MX_EMAC1_MIND_OFFSET 0x02d0 /* Ethernet Controller MAC MII Management Indicators Register */ +#define PIC32MX_EMAC1_MINDSET_OFFSET 0x02d4 +#define PIC32MX_EMAC1_MINDCLR_OFFSET 0x02d8 +#define PIC32MX_EMAC1_MINDINV_OFFSET 0x02dc + +/* Register Addresses ***********************************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +#define PIC32MX_ETH_CON1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1_OFFSET) +#define PIC32MX_ETH_CON1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1SET_OFFSET) +#define PIC32MX_ETH_CON1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1CLR_OFFSET) +#define PIC32MX_ETH_CON1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON1INV_OFFSET) +#define PIC32MX_ETH_CON2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2_OFFSET) +#define PIC32MX_ETH_CON2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2SET_OFFSET) +#define PIC32MX_ETH_CON2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2CLR_OFFSET) +#define PIC32MX_ETH_CON2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_CON2INV_OFFSET) +#define PIC32MX_ETH_TXST (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXST_OFFSET) +#define PIC32MX_ETH_TXSTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTSET_OFFSET) +#define PIC32MX_ETH_TXSTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTCLR_OFFSET) +#define PIC32MX_ETH_TXSTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_TXSTINV_OFFSET) +#define PIC32MX_ETH_RXST (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXST_OFFSET) +#define PIC32MX_ETH_RXSTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTSET_OFFSET) +#define PIC32MX_ETH_RXSTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTCLR_OFFSET) +#define PIC32MX_ETH_RXSTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXSTINV_OFFSET) +#define PIC32MX_ETH_IEN (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IEN_OFFSET) +#define PIC32MX_ETH_IENSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENSET_OFFSET) +#define PIC32MX_ETH_IENCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENCLR_OFFSET) +#define PIC32MX_ETH_IENINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENINV_OFFSET) +#define PIC32MX_ETH_IRQ (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IRQ_OFFSET) +#define PIC32MX_ETH_IENSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENSET_OFFSET) +#define PIC32MX_ETH_IENCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENCLR_OFFSET) +#define PIC32MX_ETH_IENINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_IENINV_OFFSET) +#define PIC32MX_ETH_STAT (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_STAT_OFFSET) + +/* RX Filtering Configuration Registers */ + +#define PIC32MX_ETH_RXFC (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFC_OFFSET) +#define PIC32MX_ETH_RXFCSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCSET_OFFSET) +#define PIC32MX_ETH_RXFCCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCCLR_OFFSET) +#define PIC32MX_ETH_RXFCINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXFCINV_OFFSET) +#define PIC32MX_ETH_HT0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0_OFFSET) +#define PIC32MX_ETH_HT0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0SET_OFFSET) +#define PIC32MX_ETH_HT0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0CLR_OFFSET) +#define PIC32MX_ETH_HT0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT0INV_OFFSET) +#define PIC32MX_ETH_HT1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1_OFFSET) +#define PIC32MX_ETH_HT1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1SET_OFFSET) +#define PIC32MX_ETH_HT1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1CLR_OFFSET) +#define PIC32MX_ETH_HT1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_HT1INV_OFFSET) +#define PIC32MX_ETH_PMM0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0_OFFSET) +#define PIC32MX_ETH_PMM0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0SET_OFFSET) +#define PIC32MX_ETH_PMM0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0CLR_OFFSET) +#define PIC32MX_ETH_PMM0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM0INV_OFFSET) +#define PIC32MX_ETH_PMM1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1_OFFSET) +#define PIC32MX_ETH_PMM1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1SET_OFFSET) +#define PIC32MX_ETH_PMM1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1CLR_OFFSET) +#define PIC32MX_ETH_PMM1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMM1INV_OFFSET) +#define PIC32MX_ETH_PMCS (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCS_OFFSET) +#define PIC32MX_ETH_PMCSSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSSET_OFFSET) +#define PIC32MX_ETH_PMCSCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSCLR_OFFSET) +#define PIC32MX_ETH_PMCSINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMCSINV_OFFSET) +#define PIC32MX_ETH_PMO (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMO_OFFSET) +#define PIC32MX_ETH_PMOSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOSET_OFFSET) +#define PIC32MX_ETH_PMOCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOCLR_OFFSET) +#define PIC32MX_ETH_PMOINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_PMOINV_OFFSET) + +/* Flow Control Configuring Register */ + +#define PIC32MX_ETH_RXWM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWM_OFFSET) +#define PIC32MX_ETH_RXWMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMSET_OFFSET) +#define PIC32MX_ETH_RXWMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMCLR_OFFSET) +#define PIC32MX_ETH_RXWMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXWMINV_OFFSET) + +/* Ethernet Statistics Registers */ + +#define PIC32MX_ETH_RXOVFLOW (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOW_OFFSET) +#define PIC32MX_ETH_RXOVFLOWSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWSET_OFFSET) +#define PIC32MX_ETH_RXOVFLOWCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWCLR_OFFSET) +#define PIC32MX_ETH_RXOVFLOWINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_RXOVFLOWINV_OFFSET) +#define PIC32MX_ETH_FRMTXOK (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOK_OFFSET) +#define PIC32MX_ETH_FRMTXOKSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKSET_OFFSET) +#define PIC32MX_ETH_FRMTXOKCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKCLR_OFFSET) +#define PIC32MX_ETH_FRMTXOKINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMTXOKINV_OFFSET) +#define PIC32MX_ETH_SCOLFRM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRM_OFFSET) +#define PIC32MX_ETH_SCOLFRMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMSET_OFFSET) +#define PIC32MX_ETH_SCOLFRMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMCLR_OFFSET) +#define PIC32MX_ETH_SCOLFRMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_SCOLFRMINV_OFFSET) +#define PIC32MX_ETH_MCOLFRM (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRM_OFFSET) +#define PIC32MX_ETH_MCOLFRMSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMSET_OFFSET) +#define PIC32MX_ETH_MCOLFRMCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMCLR_OFFSET) +#define PIC32MX_ETH_MCOLFRMINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_MCOLFRMINV_OFFSET) +#define PIC32MX_ETH_FRMRXOK (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOK_OFFSET) +#define PIC32MX_ETH_FRMRXOKSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKSET_OFFSET) +#define PIC32MX_ETH_FRMRXOKCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKCLR_OFFSET) +#define PIC32MX_ETH_FRMRXOKINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FRMRXOKINV_OFFSET) +#define PIC32MX_ETH_FCSERR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERR_OFFSET) +#define PIC32MX_ETH_FCSERRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRSET_OFFSET) +#define PIC32MX_ETH_FCSERRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRCLR_OFFSET) +#define PIC32MX_ETH_FCSERRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_FCSERRINV_OFFSET) +#define PIC32MX_ETH_ALGNERR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERR_OFFSET) +#define PIC32MX_ETH_ALGNERRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRSET_OFFSET) +#define PIC32MX_ETH_ALGNERRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRCLR_OFFSET) +#define PIC32MX_ETH_ALGNERRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_ETH_ALGNERRINV_OFFSET) + +/* MAC Configuration Registers */ + +#define PIC32MX_EMAC1_CFG1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1_OFFSET) +#define PIC32MX_EMAC1_CFG1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1SET_OFFSET) +#define PIC32MX_EMAC1_CFG1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1CLR_OFFSET) +#define PIC32MX_EMAC1_CFG1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG1INV_OFFSET) +#define PIC32MX_EMAC1_CFG2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2_OFFSET) +#define PIC32MX_EMAC1_CFG2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2SET_OFFSET) +#define PIC32MX_EMAC1_CFG2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2CLR_OFFSET) +#define PIC32MX_EMAC1_CFG2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CFG2INV_OFFSET) +#define PIC32MX_EMAC1_IPGT (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGT_OFFSET) +#define PIC32MX_EMAC1_IPGTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTSET_OFFSET) +#define PIC32MX_EMAC1_IPGTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTCLR_OFFSET) +#define PIC32MX_EMAC1_IPGTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGTINV_OFFSET) +#define PIC32MX_EMAC1_IPGR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGR_OFFSET) +#define PIC32MX_EMAC1_IPGRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRSET_OFFSET) +#define PIC32MX_EMAC1_IPGRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRCLR_OFFSET) +#define PIC32MX_EMAC1_IPGRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_IPGRINV_OFFSET) +#define PIC32MX_EMAC1_CLRT (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRT_OFFSET) +#define PIC32MX_EMAC1_CLRTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTSET_OFFSET) +#define PIC32MX_EMAC1_CLRTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTCLR_OFFSET) +#define PIC32MX_EMAC1_CLRTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_CLRTINV_OFFSET) +#define PIC32MX_EMAC1_MAXF (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXF_OFFSET) +#define PIC32MX_EMAC1_MAXFSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFSET_OFFSET) +#define PIC32MX_EMAC1_MAXFCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFCLR_OFFSET) +#define PIC32MX_EMAC1_MAXFINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MAXFINV_OFFSET) +#define PIC32MX_EMAC1_SUPP (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPP_OFFSET) +#define PIC32MX_EMAC1_SUPPSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPSET_OFFSET) +#define PIC32MX_EMAC1_SUPPCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPCLR_OFFSET) +#define PIC32MX_EMAC1_SUPPINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SUPPINV_OFFSET) +#define PIC32MX_EMAC1_TEST (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TEST_OFFSET) +#define PIC32MX_EMAC1_TESTSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTSET_OFFSET) +#define PIC32MX_EMAC1_TESTCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTCLR_OFFSET) +#define PIC32MX_EMAC1_TESTINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_TESTINV_OFFSET) +#define PIC32MX_EMAC1_SA0 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0_OFFSET) +#define PIC32MX_EMAC1_SA0SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0SET_OFFSET) +#define PIC32MX_EMAC1_SA0CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0CLR_OFFSET) +#define PIC32MX_EMAC1_SA0INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA0INV_OFFSET) +#define PIC32MX_EMAC1_SA1 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1_OFFSET) +#define PIC32MX_EMAC1_SA1SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1SET_OFFSET) +#define PIC32MX_EMAC1_SA1CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1CLR_OFFSET) +#define PIC32MX_EMAC1_SA1INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA1INV_OFFSET) +#define PIC32MX_EMAC1_SA2 (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2_OFFSET) +#define PIC32MX_EMAC1_SA2SET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2SET_OFFSET) +#define PIC32MX_EMAC1_SA2CLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2CLR_OFFSET) +#define PIC32MX_EMAC1_SA2INV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_SA2INV_OFFSET) + +/* MII Management Registers */ + +#define PIC32MX_EMAC1_MCFG (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFG_OFFSET) +#define PIC32MX_EMAC1_MCFGSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGSET_OFFSET) +#define PIC32MX_EMAC1_MCFGCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGCLR_OFFSET) +#define PIC32MX_EMAC1_MCFGINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCFGINV_OFFSET) +#define PIC32MX_EMAC1_MCMD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMD_OFFSET) +#define PIC32MX_EMAC1_MCMDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDSET_OFFSET) +#define PIC32MX_EMAC1_MCMDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDCLR_OFFSET) +#define PIC32MX_EMAC1_MCMDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MCMDINV_OFFSET) +#define PIC32MX_EMAC1_MADR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADR_OFFSET) +#define PIC32MX_EMAC1_MADRSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRSET_OFFSET) +#define PIC32MX_EMAC1_MADRCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRCLR_OFFSET) +#define PIC32MX_EMAC1_MADRINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MADRINV_OFFSET) +#define PIC32MX_EMAC1_MWTD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTD_OFFSET) +#define PIC32MX_EMAC1_MWTDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDSET_OFFSET) +#define PIC32MX_EMAC1_MWTDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDCLR_OFFSET) +#define PIC32MX_EMAC1_MWTDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MWTDINV_OFFSET) +#define PIC32MX_EMAC1_MRDD (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDD_OFFSET) +#define PIC32MX_EMAC1_MRDDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDSET_OFFSET) +#define PIC32MX_EMAC1_MRDDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDCLR_OFFSET) +#define PIC32MX_EMAC1_MRDDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MRDDINV_OFFSET ) +#define PIC32MX_EMAC1_MIND (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MIND_OFFSET) +#define PIC32MX_EMAC1_MINDSET (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDSET_OFFSET) +#define PIC32MX_EMAC1_MINDCLR (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDCLR_OFFSET) +#define PIC32MX_EMAC1_MINDINV (PIC32MX_ETHERNET_K1BASE+PIC32MX_EMAC1_MINDINV_OFFSET) + +/* Register Bit-Field Definitions ***********************************************************/ + +/* Controller and DMA Engine Configuration/Status Registers */ + +/* Ethernet Controller Control 1 Register */ +#define ETH_CON1_ +/* Ethernet Controller Control 2 Register */ +#define ETH_CON2_ +/* Ethernet Controller TX Packet Descriptor Start Address Register */ +#define ETH_TXST_ +/* Ethernet Controller RX Packet Descriptor Start Address Register */ +#define ETH_RXST_ +/* Ethernet Controller Interrupt Enable Register */ +#define ETH_IEN_ +/* Ethernet Controller Interrupt Request Register */ +#define ETH_IRQ_ +/* Ethernet Controller Status Register */ +#define ETH_STAT_ + +/* RX Filtering Configuration Registers */ + +/* Ethernet Controller Receive Filter Configuration Register */ +#define ETH_RXFC_ +/* Ethernet Controller Hash Table 0 Register */ +#define ETH_HT0_ +/* Ethernet Controller Hash Table 1 Register */ +#define ETH_HT1_ +/* Ethernet Controller Pattern Match Mask 0 Register */ +#define ETH_PMM0_ +/* Ethernet Controller Pattern Match Mask 1 Register */ +#define ETH_PMM1_ +/* Ethernet Controller Pattern Match Checksum Register */ +#define ETH_PMCS_ +/* Ethernet Controller Pattern Match Offset Register */ +#define ETH_PMO_ + +/* Flow Control Configuring Register */ + +/* Ethernet Controller Receive Watermarks Register */ +#define ETH_RXWM_ + +/* Ethernet Statistics Registers */ + +/* Ethernet Controller Receive Overflow Statistics Register */ +#define ETH_RXOVFLOW_ +/* Ethernet Controller Frames Transmitted OK Statistics Register */ +#define ETH_FRMTXOK_ +/* Ethernet Controller Single Collision Frames Statistics Register */ +#define ETH_SCOLFRM_ +/* Ethernet Controller Multiple Collision Frames Statistics Register */ +#define ETH_MCOLFRM_ +/* Ethernet Controller Frames Received OK Statistics Register */ +#define ETH_FRMRXOK_ +/* Ethernet Controller Frame Check Sequence Error Statistics Register */ +#define ETH_FCSERR_ +/* Ethernet Controller Alignment Errors Statistics Register */ +#define ETH_ALGNERR_ + +/* MAC Configuration Registers */ + +/* Ethernet Controller MAC Configuration 1 Register */ + +#define EMAC1_CFG1_RXEN (1 << 0) /* Bit 0: MAC Receive enable */ +#define EMAC1_CFG1_PASSALL (1 << 1) /* Bit 1: MAC Pass all all receive frames */ +#define EMAC1_CFG1_PXPAUSE (1 << 2) /* Bit 2: MAC RX flow control bit */ +#define EMAC1_CFG1_TXPAUSE (1 << 3) /* Bit 3: MAC TX flow control */ +#define EMAC1_CFG1_LOOPBACK (1 << 4) /* Bit 4: MAC loopback mode */ + /* Bits 5-7: Reserved */ +#define EMAC1_CFG1_TXRST (1 << 8) /* Bit 8: Reset TX function */ +#define EMAC1_CFG1_MCSTXRST (1 << 9) /* Bit 9: Reset MCS/TX */ +#define EMAC1_CFG1_RXRST (1 << 10) /* Bit 10: Reset RX */ +#define EMAC1_CFG1_MCSRXRST (1 << 11) /* Bit 11: Reset MCS/RX */ + /* Bits 12-13: Reserved */ +#define EMAC1_CFG1_SIMRST (1 << 14) /* Bit 14: Simulation reset */ +#define EMAC1_CFG1_SOFTRST (1 << 15) /* Bit 15: Soft reset */ + /* Bits 16-31: Reserved */ + +/* Ethernet Controller MAC Configuration 2 Register */ + +#define EMAC1_CFG2_FULLDPLX: (1 << 0) /* Bit 0: Full duplex operation */ +#define EMAC1_CFG2_LENGTHCK (1 << 1) /* Bit 1: Frame length checking */ +#define EMAC1_CFG2_HUGEFRM (1 << 2) /* Bit 2: Huge frame enable */ +#define EMAC1_CFG2_DELAYCRC (1 << 3) /* Bit 3: Delayed CRC */ +#define EMAC1_CFG2_CRCEN (1 << 4) /* Bit 4: CRC enable */ +#define EMAC1_CFG2_PADCRCEN (1 << 5) /* Bit 5: Pad/CRC enable */ +#define EMAC1_CFG2_VLANPADEN (1 << 6) /* Bit 6: VLAN pad enable */ +#define EMAC1_CFG2_AUTOPADEN (1 << 7) /* Bit 7: Auto detect pad enable */ +#define EMAC1_CFG1_PUREPRE (1 << 8) /* Bit 8: Pure preamble enforcement */ +#define EMAC1_CFG1_LONGPRE (1 << 9) /* Bit 9: Long preamble enforcement */ + /* Bits 10-11: Reserved */ +#define EMAC1_CFG2_NOBKOFF (1 << 12) /* Bit 12: No backoff */ +#define EMAC1_CFG2_BPNOBKOFF (1 << 13) /* Bit 13: Back pressure/no backoff */ +#define EMAC1_CFG2_EXCESSDFR (1 << 14) /* Bit 14: Excess defer */ + /* Bits 15-31: Reserved */ + +/* Ethernet Controller MAC Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGT_SHIFT (0) /* Bits 0-6 */ +#define EMAC1_IPGT_MASK (0x7f << EMAC1_IPGT_SHIFT) + /* Bits 7-31: Reserved */ +/* Ethernet Controller MAC Non-Back-to-Back Interpacket Gap Register */ + +#define EMAC1_IPGR_GAP2_SHIFT (0) /* Bits 0-6: Gap part 2 */ +#define EMAC1_IPGR_GAP2_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bit 7: Reserved */ +#define EMAC1_IPGR_GAP1_SHIFT (8) /* Bits 8-18: Gap part 1 */ +#define EMAC1_IPGR_GAP1_MASK (0x7f << EMAC1_IPGR_GAP2_SHIFT) + /* Bits 15-31: Reserved */ +/* Ethernet Controller MAC Collision Window/Retry Limit Register */ + +#define EMAC1_CLRT_RETX_SHIFT (0) /* Bits 0-3: Retransmission maximum */ +#define EMAC1_CLRT_RETX_MASK (15 << EMAC1_CLRT_RETX_SHIFT) + /* Bits 4-7: Reserved */ +#define EMAC1_CLRT_CWINDOW_SHIFT (8) /* Bits 8-13: Collision window */ +#define EMAC1_CLRT_CWINDOW_MASK (0x3f << EMAC1_CLRT_CWINDOW_SHIFT) + /* Bits 14-31: Reserved */ +/* Ethernet Controller MAC Maximum Frame Length Register */ + +#define EMAC1_MAXF_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MAXF_MASK (0xffff << EMAC1_MAXF_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC PHY Support Register */ +#define EMAC1_SUPP_ + /* Bits 0-7: Reserved */ +#define EMAC1_SUPP_SPEEDRMII (1 << 8) /* Bit 8: RMII Speed0=10Bps 1=100Bps */ + /* Bits 9-10: Reserved */ +#define EMAC1_SUPP_RESETRMII (1 << 11) /* Bit 11: Reset RMII Logic */ + /* Bits 12-31: Reserved */ +/* Ethernet Controller MAC Test Register */ + +#define EMAC1_TEST_SHRTQNTA (1 << 0) /* Bit 0: Shortcut pause quanta */ +#define EMAC1_TEST_TESTPAUSE (1 << 1) /* Bit 1: Test pause */ +#define EMAC1_TEST_TESTBP (1 << 2) /* Bit 2: Test packpressure */ + /* Bits 3-31: Reserved */ +/* Ethernet Controller MAC Station Address 0 Register */ + +#define EMAC1_SA0_STNADDR6_SHIFT (0) /* Bits 0-7: Station address 5th octet */ +#define EMAC1_SA0_STNADDR6_MASK (0xff << EMAC1_SA0_STNADDR6_SHIFT) +#define EMAC1_SA0_STNADDR5_SHIFT (8) /* Bits 8-15: Station address 6th octet */ +#define EMAC1_SA0_STNADDR5_MASK (0xff << EMAC1_SA0_STNADDR5_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 1 Register */ + +#define EMAC1_SA1_STNADDR4_SHIFT (0) /* Bits 0-7: Station address 4th octet */ +#define EMAC1_SA1_STNADDR4_MASK (0xff << EMAC1_SA0_STNADDR4_SHIFT) +#define EMAC1_SA1_STNADDR3_SHIFT (8) /* Bits 8-15: Station address 3rd octet */ +#define EMAC1_SA1_STNADDR3_MASK (0xff << EMAC1_SA0_STNADDR3_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC Station Address 2 Register */ + +#define EMAC1_SA2_STNADDR2_SHIFT (0) /* Bits 0-7: Station address 2nd octet */ +#define EMAC1_SA2_STNADDR2_MASK (0xff << EMAC1_SA2_STNADDR2_SHIFT) +#define EMAC1_SA2_STNADDR1_SHIFT (8) /* Bits 8-15: Station address 1st octet */ +#define EMAC1_SA2_STNADDR1_MASK (0xff << EMAC1_SA2_STNADDR1_SHIFT) + /* Bits 16-31: Reserved */ +/* MII Management Registers */ + +/* Ethernet Controller MAC MII Management Configuration Register */ + +#define EMAC1_MCFG_SCANINC (1 << 0) /* Bit 0: Scan increment */ +#define EMAC1_MCFG_NOPRE (1 << 1) /* Bit 1: Suppress preamble */ +#define EMAC1_MCFG_CLKSEL_SHIFT (2) /* Bits 2-5: Clock select */ +#define EMAC1_MCFG_CLKSEL_MASK (15 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV4 (0 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV6 (2 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV8 (3 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV10 (4 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV14 (5 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV20 (6 << EMAC1_MCFG_CLKSEL_SHIFT) +# define EMAC1_MCFG_CLKSEL_DIV40 (8 << EMAC1_MCFG_CLKSEL_SHIFT) + /* Bits 6-14: Reserved */ +#define EMAC1_MCFG_MGMTRST (1 << 15) /* Bit 15: Reset MII mgmt */ + /* Bits 16-31: Reserved */ + +/* Ethernet Controller MAC MII Management Command Register */ + +#define EMAC1_MCMD_READ (1 << 0) /* Bit 0: Single read cycle */ +#define EMAC1_MCMD_SCAN (1 << 1) /* Bit 1: Continuous read cycles */ + /* Bits 2-31: Reserved */ +#define EMAC1_MCMD_WRITE (0) + +/* Ethernet Controller MAC MII Management Address Register */ + +#define EMAC1_MADR_REGADDR_SHIFT (0) /* Bits 0-4: Register address */ +#define EMAC1_MADR_REGADDR_MASK (31 << EMAC1_MADR_REGADDR_SHIFT) + /* Bits 7-5: Reserved */ +#define EMAC1_MADR_PHYADDR_SHIFT (8) /* Bits 8-12: PHY address */ +#define EMAC1_MADR_PHYADDR_MASK (31 << EMAC1_MADR_PHYADDR_SHIFT) + /* Bits 13-31: Reserved */ +/* Ethernet Controller MAC MII Management Write Data Register */ + +#define EMAC1_MWTD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MWTD_MASK (0xffff << EMAC1_MWTD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Read Data Register */ + +#define EMAC1_MRDD_SHIFT (0) /* Bits 0-15 */ +#define EMAC1_MRDD_MASK (0xffff << EMAC1_MRDD_SHIFT) + /* Bits 16-31: Reserved */ +/* Ethernet Controller MAC MII Management Indicators Register */ + +#define EMAC1_MIND_MIIMBUSY (1 << 0) /* Bit 0: Busy */ +#define EMAC1_MIND_SCAN (1 << 1) /* Bit 1: Scanning */ +#define EMAC1_MIND_NOTVALID (1 << 2) /* Bit 2: Not valid */ +#define EMAC1_MIND_LINKFAIL (1 << 3) /* Bit 3: MII link fail */ + /* Bits 4-31: Reserved */ + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/******************************************************************************************** + * Inline Functions + ********************************************************************************************/ + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MIPS_SRC_PIC32MX_PIC32MX_ETHERNET_H */ diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h b/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h index 472d607d1..a3fe2791c 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-memorymap.h @@ -187,7 +187,7 @@ # define PIC32MX_CHE_K1BASE (PIC32MX_SFR_K1BASE + 0x00084000) -/* USB2 Register Base Addresses */ +/* USBOTG Register Base Addresses */ # define PIC32MX_USB_K1BASE (PIC32MX_SFR_K1BASE + 0x00085000) @@ -200,17 +200,17 @@ # define PIC32MX_IOPORTE 4 # define PIC32MX_IOPORTF 5 # define PIC32MX_IOPORTG 6 -# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) +# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) -# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) -# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) -# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) -# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) -# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) -# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) -# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) +# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) +# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) +# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) +# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) +# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) +# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) +# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) -# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) +# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) #elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) @@ -330,7 +330,7 @@ # define PIC32MX_CHE_K1BASE (PIC32MX_SFR_K1BASE + 0x00084000) -/* USB2 Register Base Addresses */ +/* USBOTG Register Base Addresses */ # define PIC32MX_USB_K1BASE (PIC32MX_SFR_K1BASE + 0x00085000) @@ -343,17 +343,26 @@ # define PIC32MX_IOPORTE 4 # define PIC32MX_IOPORTF 5 # define PIC32MX_IOPORTG 6 -# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) +# define PIC32MX_IOPORT_K1BASE(n) (PIC32MX_SFR_K1BASE + 0x00086000 + 0x40*(n)) -# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) -# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) -# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) -# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) -# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) -# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) -# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) +# define PIC32MX_IOPORTA_K1BASE (PIC32MX_SFR_K1BASE + 0x00086000) +# define PIC32MX_IOPORTB_K1BASE (PIC32MX_SFR_K1BASE + 0x00086040) +# define PIC32MX_IOPORTC_K1BASE (PIC32MX_SFR_K1BASE + 0x00086080) +# define PIC32MX_IOPORTD_K1BASE (PIC32MX_SFR_K1BASE + 0x000860c0) +# define PIC32MX_IOPORTE_K1BASE (PIC32MX_SFR_K1BASE + 0x00086100) +# define PIC32MX_IOPORTF_K1BASE (PIC32MX_SFR_K1BASE + 0x00086140) +# define PIC32MX_IOPORTG_K1BASE (PIC32MX_SFR_K1BASE + 0x00086180) -# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) +# define PIC32MX_IOPORTCN_K1BASE (PIC32MX_SFR_K1BASE + 0x000861c0) + +/* Ethernet Controller Register Base Addresses */ + +# define PIC32MX_ETHERNET_K1BASE (PIC32MX_SFR_K1BASE + 0x00089000) + +/* CAN1/2 Register Base Addresses */ + +# define PIC32MX_CAN1_K1BASE (PIC32MX_SFR_K1BASE + 0x0008b000) +# define PIC32MX_CAN2_K1BASE (PIC32MX_SFR_K1BASE + 0x0008c000) #else # error "Memory map unknown for this PIC32 chip" |