From 714af6ebb838f2cf0722ffb79a7602e4842f1544 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 17 Mar 2015 14:29:41 -0600 Subject: [PATCH] SAMV7 Ethernet: Support getting IP address from the XULT AT24 EEPROM --- arch/arm/src/samv7/sam_twihs.c | 68 +++++++++++------- configs/sama5d4-ek/src/sam_ethernet.c | 2 +- configs/samv71-xult/README.txt | 11 ++- configs/samv71-xult/src/sam_bringup.c | 18 ++++- configs/samv71-xult/src/sam_ethernet.c | 98 +++++++++++++++++++++++++- configs/samv71-xult/src/samv71-xult.h | 20 ++++++ 6 files changed, 184 insertions(+), 33 deletions(-) diff --git a/arch/arm/src/samv7/sam_twihs.c b/arch/arm/src/samv7/sam_twihs.c index 3f53c2f352..7ab1e407ac 100644 --- a/arch/arm/src/samv7/sam_twihs.c +++ b/arch/arm/src/samv7/sam_twihs.c @@ -164,6 +164,7 @@ struct twi_dev_s #endif uint16_t address; /* Slave address */ uint16_t flags; /* Transfer flags */ + bool initd; /* True :device has been initialized */ uint8_t msgc; /* Number of message in the message list */ sem_t exclsem; /* Only one thread can access at a time */ @@ -1428,36 +1429,46 @@ struct i2c_dev_s *up_i2cinitialize(int bus) flags = irqsave(); - /* Allocate a watchdog timer */ + /* Has the device already been initialized? */ - priv->timeout = wd_create(); - if (priv->timeout == NULL) + if (!priv->initd) { - idbg("ERROR: Failed to allocate a timer\n"); - goto errout_with_irq; + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + if (priv->timeout == NULL) + { + idbg("ERROR: Failed to allocate a timer\n"); + goto errout_with_irq; + } + + /* Attach Interrupt Handler */ + + ret = irq_attach(priv->attr->irq, priv->attr->handler); + if (ret < 0) + { + idbg("ERROR: Failed to attach irq %d\n", priv->attr->irq); + goto errout_with_wdog; + } + + /* Initialize the TWIHS driver structure */ + + priv->dev.ops = &g_twiops; + priv->address = 0; + priv->flags = 0; + + (void)sem_init(&priv->exclsem, 0, 1); + (void)sem_init(&priv->waitsem, 0, 0); + + /* Perform repeatable TWIHS hardware initialization */ + + twi_hw_initialize(priv, frequency); + + /* Now it has been initialized */ + + priv->initd = true; } - /* Attach Interrupt Handler */ - - ret = irq_attach(priv->attr->irq, priv->attr->handler); - if (ret < 0) - { - idbg("ERROR: Failed to attach irq %d\n", priv->attr->irq); - goto errout_with_wdog; - } - - /* Initialize the TWIHS driver structure */ - - priv->dev.ops = &g_twiops; - priv->address = 0; - priv->flags = 0; - - (void)sem_init(&priv->exclsem, 0, 1); - (void)sem_init(&priv->waitsem, 0, 0); - - /* Perform repeatable TWIHS hardware initialization */ - - twi_hw_initialize(priv, frequency); irqrestore(flags); return &priv->dev; @@ -1481,11 +1492,13 @@ errout_with_irq: int up_i2cuninitialize(FAR struct i2c_dev_s *dev) { struct twi_dev_s *priv = (struct twi_dev_s *) dev; + irqstate_t flags; i2cvdbg("TWIHS%d Un-initializing\n", priv->attr->twi); /* Disable TWIHS interrupts */ + flags = irqsave(); up_disable_irq(priv->attr->irq); /* Reset data structures */ @@ -1501,6 +1514,9 @@ int up_i2cuninitialize(FAR struct i2c_dev_s *dev) /* Detach Interrupt Handler */ (void)irq_detach(priv->attr->irq); + + priv->initd = false; + irqrestore(flags); return OK; } diff --git a/configs/sama5d4-ek/src/sam_ethernet.c b/configs/sama5d4-ek/src/sam_ethernet.c index 9d87840856..c61082890b 100644 --- a/configs/sama5d4-ek/src/sam_ethernet.c +++ b/configs/sama5d4-ek/src/sam_ethernet.c @@ -109,7 +109,7 @@ static xcpt_t g_emac1_handler; ************************************************************************************/ /************************************************************************************ - * Name: sam_emac_phy_enable and sam_gmac_enable + * Name: sam_emac0/1_phy_enable ************************************************************************************/ #ifdef CONFIG_SAMA5_PIOE_IRQ diff --git a/configs/samv71-xult/README.txt b/configs/samv71-xult/README.txt index 1afa25013c..f8046f01ac 100644 --- a/configs/samv71-xult/README.txt +++ b/configs/samv71-xult/README.txt @@ -396,6 +396,8 @@ Selecting the GMAC peripheral System Type -> SAMV7 Peripheral Support CONFIG_SAMV7_EMAC0=y : Enable the GMAC peripheral (aka, EMAC0) + CONFIG_SAMV7_TWIHS0=y : We will get the MAC address from the AT24 EEPROM + CONFIG_SAMV7_TWIHS0_FREQUENCY=100000 System Type -> EMAC device driver options CONFIG_SAMV7_EMAC0_NRXBUFFERS=16 : Set aside some RS and TX buffers @@ -434,6 +436,13 @@ Selecting the GMAC peripheral CONFIG_NETDEVICES=y : Enabled PHY selection CONFIG_ETH0_PHY_KSZ8061=y : Select the KSZ8061 PHY used with EMAC0 + Device drivers -> Memory Technology Devices + CONFIG_MTD_AT24XX=y : Enable the AT24 device driver + CONFIG_AT24XX_SIZE=2 : Normal EEPROM is 2Kbit (256b) + CONFIG_AT24XX_ADDR=0x57 : Normal EEPROM address */ + CONFIG_AT24XX_EXTENDED=y : Supports an extended memory region + CONFIG_AT24XX_EXTSIZE=160 : Extended address up to 0x9f + Application Configuration -> Network Utilities CONFIG_NETUTILS_DNSCLIENT=y : Enable host address resolution CONFIG_NETUTILS_TELNETD=y : Enable the Telnet daemon @@ -446,7 +455,7 @@ Selecting the GMAC peripheral CONFIG_NSH_IPADDR=0x0a000002 : Select an IP address CONFIG_NSH_DRIPADDR=0x0a000001 : IP address of gateway/host PC CONFIG_NSH_NETMASK=0xffffff00 : Netmask - CONFIG_NSH_NOMAC=y : Need to make up a bogus MAC address + CONFIG_NSH_NOMAC=n : We will get the IP address from EEPROM : Defaults should be okay for other options Using the network with NSH diff --git a/configs/samv71-xult/src/sam_bringup.c b/configs/samv71-xult/src/sam_bringup.c index 50ae3951dd..5f8ceed9af 100644 --- a/configs/samv71-xult/src/sam_bringup.c +++ b/configs/samv71-xult/src/sam_bringup.c @@ -89,12 +89,24 @@ int sam_bringup(void) { -#if defined(HAVE_HSMCI) || defined(HAVE_USBHOST) || defined(HAVE_USBMONITOR) || \ - defined(HAVE_WM8904) || defined(HAVE_AUTOMOUNTER) || defined(HAVE_ELF) || \ - defined(HAVE_ROMFS) +#if defined(HAVE_MACADDR) || defined(HAVE_HSMCI) || defined(HAVE_USBHOST) || \ + defined(HAVE_USBMONITOR) || defined(HAVE_WM8904) || \ + defined(HAVE_AUTOMOUNTER) || defined(HAVE_ELF) || defined(HAVE_ROMFS) int ret; #endif +#ifdef HAVE_MACADDR + /* Read the Ethernet MAC address from the AT24 FLASH and configure the + * Ethernet driver with that address. + */ + + ret = sam_emac0_setmac(); + if (ret < 0) + { + SYSLOG("ERROR: sam_emac0_setmac() failed: %d\n", ret); + } +#endif + #ifdef HAVE_HSMCI #ifdef CONFIG_SAMV7_HSMCI0 /* Initialize the HSMCI0 driver */ diff --git a/configs/samv71-xult/src/sam_ethernet.c b/configs/samv71-xult/src/sam_ethernet.c index 966886ec9e..d8e5ed6e58 100644 --- a/configs/samv71-xult/src/sam_ethernet.c +++ b/configs/samv71-xult/src/sam_ethernet.c @@ -50,12 +50,16 @@ #include #include +#include #include #include #include +#include +#include #include "sam_gpio.h" +#include "sam_twihs.h" #include "sam_ethernet.h" #include "samv71-xult.h" @@ -68,6 +72,8 @@ #define SAMV7_EMAC0_DEVNAME "eth0" +#define AT24XX_MACADDR_OFFSET 0x9a + /* Debug ********************************************************************/ /* Extra, in-depth debug output that is only available if * CONFIG_NETDEV_PHY_DEBUG us defined. @@ -94,7 +100,7 @@ static xcpt_t g_emac0_handler; ************************************************************************************/ /************************************************************************************ - * Name: sam_emac_phy_enable and sam_gmac_enable + * Name: sam_emac0_phy_enable ************************************************************************************/ #ifdef CONFIG_SAMV7_PIOA_IRQ @@ -126,10 +132,99 @@ static void sam_emac0_phy_enable(bool enable) void weak_function sam_netinitialize(void) { + /* Configure the PHY interrupt GPIO */ + phydbg("Configuring %08x\n", GPIO_INT_ETH0); sam_configgpio(GPIO_INT_ETH0); } +/************************************************************************************ + * Name: sam_emac0_setmac + * + * Description: + * Read the Ethernet MAC address from the AT24 FLASH and configure the Ethernet + * driver with that address. + * + ************************************************************************************/ + +#ifdef HAVE_MACADDR +int sam_emac0_setmac(void) +{ + struct i2c_dev_s *i2c; + struct mtd_dev_s *at24; + uint8_t mac[6]; + ssize_t nread; + int ret; + + /* Get an instance of the TWI0 interface */ + + i2c = up_i2cinitialize(0); + if (!i2c) + { + ndbg("ERROR: Failed to initialize TWI0\n"); + return -ENODEV; + } + + /* Initialize the AT24 driver */ + + at24 = at24c_initialize(i2c); + if (!at24) + { + ndbg("ERROR: Failed to initialize the AT24 driver\n"); + (void)up_i2cuninitialize(i2c); + return -ENODEV; + } + + /* Configure the AT24 to access the extended memory region */ + + ret = at24->ioctl(at24, MTDIOC_EXTENDED, 1); + if (ret < 0) + { + ndbg("ERROR: AT24 ioctl(MTDIOC_EXTENDED) failed: %d\n", ret); + (void)up_i2cuninitialize(i2c); + return ret; + } + + /* Read the MAC address */ + + nread = at24->read(at24, AT24XX_MACADDR_OFFSET, 6, mac); + if (nread < 6) + { + ndbg("ERROR: AT24 read(AT24XX_MACADDR_OFFSET) failed: ld\n", (long)nread); + (void)up_i2cuninitialize(i2c); + return (int)nread; + } + + /* Put the AT24 back in normal memory access mode */ + + ret = at24->ioctl(at24, MTDIOC_EXTENDED, 0); + if (ret < 0) + { + ndbg("ERROR: AT24 ioctl(MTDIOC_EXTENDED) failed: %d\n", ret); + } + + /* Release the I2C instance. + * REVISIT: Need an interface to release the AT24 instance too + */ + + ret = up_i2cuninitialize(i2c); + if (ret < 0) + { + ndbg("ERROR: Failed to release the I2C interface: %d\n", ret); + } + + nvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + /* Now configure the EMAC driver to use this MAC address */ +#warning Missing logic + + return OK; +} +#else +# define sam_emac0_setmac() +#endif + /**************************************************************************** * Name: arch_phy_irq * @@ -207,7 +302,6 @@ xcpt_t arch_phy_irq(FAR const char *intf, xcpt_t handler, phy_enable_t *enable) nvdbg("%s: handler=%p\n", intf, handler); phydbg("EMAC0: devname=%s\n", SAMV7_EMAC0_DEVNAME); - phydbg("EMAC1: devname=%s\n", SAMV7_EMAC1_DEVNAME); if (strcmp(intf, SAMV7_EMAC0_DEVNAME) == 0) { diff --git a/configs/samv71-xult/src/samv71-xult.h b/configs/samv71-xult/src/samv71-xult.h index db74840c6b..f8ee00ac5d 100644 --- a/configs/samv71-xult/src/samv71-xult.h +++ b/configs/samv71-xult/src/samv71-xult.h @@ -59,6 +59,7 @@ #define HAVE_USBDEV 1 #define HAVE_USBMONITOR 1 #define HAVE_NETWORK 1 +#define HAVE_MACADDR 1 /* HSMCI */ /* Can't support MMC/SD if the card interface is not enabled */ @@ -160,6 +161,12 @@ #if !defined(CONFIG_NET) || !defined(CONFIG_SAMV7_EMAC) # undef HAVE_NETWORK +# undef HAVE_MACADDR +#endif + +#if defined(CONFIG_NSH_NOMAC) || !defined(CONFIG_SAMV7_TWIHS0) || \ + !defined(CONFIG_MTD_AT24XX) || !defined(CONFIG_AT24XX_EXTENDED) +# undef HAVE_MACADDR #endif /* SAMV71-XULT GPIO Pin Definitions *************************************************/ @@ -365,6 +372,19 @@ int sam_hsmci_initialize(int slot, int minor); void weak_function sam_netinitialize(void); #endif +/************************************************************************************ + * Name: sam_emac0_setmac + * + * Description: + * Read the Ethernet MAC address from the AT24 FLASH and configure the Ethernet + * driver with that address. + * + ************************************************************************************/ + +#ifdef HAVE_MACADDR +int sam_emac0_setmac(void); +#endif + /************************************************************************************ * Name: sam_cardinserted *