Forum: Mikrocontroller und Digitale Elektronik LPC1768 Ethernet mit DP83848J


von Alexander F. (alexf91)


Angehängte Dateien:

Lesenswert?

Ich versuche derzeit, einen DP83848J PHY an einem LPC1768 zum laufen zu 
bringen. Genauer gesagt verwende ich ein Eval Board von steitec.net 
(http://www.steitec.net/ARM-Boards/ARM-LPC1768-Cortex-M3-LCD-Board.html).

Als ersten Versuch wollte ich einfach ein Ethernet Paket versenden, doch 
das scheitert schon an der Initialisierung. Als Library verwende ich das 
CMSIS von NXP, welches für einen DP83848C geschrieben ist (wird 
jedenfalls immer im Code erwähnt), das sollte aber kein Problem 
darstellen.

Das Problem tritt beim Reset in der Funktion EMAC_Init() ab Zeile 331 
auf. Dieser sollte laut Datenblatt etwa 1µs dauern, bei mir dauert es 
jedoch mehrere Sekunden bis statt 0x00000000 0x0000FFFF aus dem 
Control-Register gelesen wird.
Dieser Wert wird jedoch auch aus jedem anderem Register gelesen, was 
offensichtlich nicht richtig sein kann.

Hat jemand anderer auch ähnliche Probleme bzw. eine Lösung?
Könnte vielleicht ein Hardwaredefekt vorliegen?

Datenblatt:
http://www.national.com/pf/DP/DP83848J.html#Overview
LPC17xx User Manual:
http://www.nxp.com/documents/user_manual/UM10360.pdf

von juergen (Gast)


Lesenswert?

Hallo,

ich hatte ähnliche Probleme. Bei mir lags daran, daß der LPC zum 
Zeitpunkt der Emac-Initialisierung schom mit 120MHz lief und das wohl zu 
schnell für den EMAC ist. Folgende Zeilen brachten die Erlösung:

#define MCFG_CLK_DIV64    0x0000003c

  /* Enable Reduced MII interface. */
  LPC_EMAC->MCFG = MCFG_CLK_DIV64 | MCFG_RES_MII;
  for (tout = 100; tout; tout--);
  LPC_EMAC->MCFG = MCFG_CLK_DIV64;

Ich bin ehrlich, zur kompletten Lektüre des Ethernetteils des LPC bin 
ich noch nicht gekommen, deshalb verstehe ich die Zusammenhänge noch 
nicht komplett. Das EasyWeb-Example ist in vielen leicht 
unterschiedlichen Versionen im Umlauf, und in einem von diesen habe ich 
diesen Codeschnipsel entdeckt. Ich hatte auch den Effekt, dass alle 
gelesenen Werte auf 0xffff standen.
Hier noch meine EMAC_Ini() die auch das aktuelle LPCXpresso 
berücksichtigt (LPC1769 und geänderter PHY):



#define MCFG_CLK_DIV64    0x0000003c

void EMAC_Init(void)
{
// Keil: function modified to access the EMAC
// Initializes the EMAC ethernet controller
  unsigned int regv,tout,phyid1,phyid2;
  unsigned phy_in_use = 0;
  unsigned phy_linkstatus_reg;
  unsigned phy_linkstatus_mask;

  /* Power Up the EMAC controller. */
  LPC_SC->PCONP |= (0x1<<30);

  LPC_PINCON->PINSEL2 = 0x50150105;
  LPC_PINCON->PINSEL3 &= ~0x0000000F;
  LPC_PINCON->PINSEL3 |= 0x00000005;

  /* Reset all EMAC internal modules. */
  LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | 
MAC1_RES_MCS_RX |
             MAC1_SIM_RES | MAC1_SOFT_RES;
  LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES;

  /* A short delay after reset. */
  for (tout = 100; tout; tout--);

  /* Initialize MAC control registers. */
  LPC_EMAC->MAC1 = MAC1_PASS_ALL;
  LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
  LPC_EMAC->MAXF = ETH_MAX_FLEN;
  LPC_EMAC->CLRT = CLRT_DEF;
  LPC_EMAC->IPGR = IPGR_DEF;

  /* Enable Reduced MII interface. */
  LPC_EMAC->MCFG = MCFG_CLK_DIV64 | MCFG_RES_MII;
  for (tout = 100; tout; tout--);
  LPC_EMAC->MCFG = MCFG_CLK_DIV64;

  /* Enable Reduced MII interface. */
  LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM;

  /* Reset Reduced MII Logic. */
  LPC_EMAC->SUPP = SUPP_RES_RMII;
  for (tout = 100; tout; tout--);
  LPC_EMAC->SUPP = 0;

  /* Put the DP83848C in reset mode */
  write_PHY (PHY_REG_BMCR, 0x8000);

  /* Wait for hardware reset to end. */
  for (tout = 0; tout < 0x100000; tout++)
    {
    regv = read_PHY (PHY_REG_BMCR);
    if (!(regv & 0x8000))
      break; // Reset complete
    }

  /* Check if this is a DP83848C PHY. */
  phyid1 = read_PHY (PHY_REG_IDR1);
  phyid2 = read_PHY (PHY_REG_IDR2);

  if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == DP83848C_ID)
    phy_in_use =  DP83848C_ID;
  else if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == LAN8720_ID)
    phy_in_use = LAN8720_ID;

  if (phy_in_use != 0)
    {
    /* Configure the PHY device */
    /* Use autonegotiation about the link speed. */
    write_PHY (PHY_REG_BMCR, PHY_AUTO_NEG);
    /* Wait to complete Auto_Negotiation. */
    for (tout = 0; tout < 0x100000; tout++)
      {
      regv = read_PHY (PHY_REG_BMSR);
      if (regv & 0x0020)
        break; // Autonegotiation Complete.
      }
    }

  phy_linkstatus_reg = PHY_REG_STS;    // Default to DP83848C
  phy_linkstatus_mask = 0x0001;

  if (phy_in_use == LAN8720_ID)
    {
    phy_linkstatus_reg = PHY_REG_BMSR;
    phy_linkstatus_mask = 0x0004;
    }

  /* Check the link status. */
  for (tout = 0; tout < 0x10000; tout++)
    {
    regv = read_PHY (phy_linkstatus_reg);
    if (regv  & phy_linkstatus_mask)
      break; // Link is on.
    }

  /* Configure Full/Half Duplex mode. */
  if (regv & 0x0004)
    {
    /* Full duplex is enabled. */
    LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
    LPC_EMAC->Command |= CR_FULL_DUP;
    LPC_EMAC->IPGT     = IPGT_FULL_DUP;
    }
  else
    {
    /* Half duplex mode. */
    LPC_EMAC->IPGT = IPGT_HALF_DUP;
    }

  /* Configure 100MBit/10MBit mode. */
  if (regv & 0x0002)
    LPC_EMAC->SUPP = 0;  /* 10MBit mode. */
  else
    LPC_EMAC->SUPP = SUPP_SPEED; /* 100MBit mode. */

  /* Set the Ethernet MAC Address registers */
  LPC_EMAC->SA0 = (UIP_ETHADDR5 << 8) | UIP_ETHADDR4;
  LPC_EMAC->SA1 = (UIP_ETHADDR3 << 8) | UIP_ETHADDR2;
  LPC_EMAC->SA2 = (UIP_ETHADDR1 << 8) | UIP_ETHADDR0;

  /* Initialize Tx and Rx DMA Descriptors */
  rx_descr_init ();
  tx_descr_init ();

  /* Receive Broadcast and Perfect Match Packets */
  LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;

  /* Enable EMAC interrupts. */
  LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;

  /* Reset all interrupts */
  LPC_EMAC->IntClear  = 0xFFFF;

  /* Enable receive and transmit mode of MAC Ethernet core */
  LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
  LPC_EMAC->MAC1     |= MAC1_REC_EN;
}

von Alexander F. (alexf91)


Lesenswert?

Der zu hohe Takt scheint wirklich ein Problem gewesen zu sein.
Mit einem Vorteiler von 64 läuft der Reset wirklich innerhalb der im 
Datenblatt angegebenen Zeit ab. Jetzt wird aus dem ID1 Register statt 
0xFFFF 0x0FFF ausgelesen, aus den anderen aber weiterhin 0xFFFF.
Irgendwo muss also noch ein Fehler sein. Ich werde jetzt weiter 
probieren, wenn es Fortschritte gibt melde ich mich nochmal.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.