[En-Nut-Discussion] (no subject)

Rasmus Aagesen rasmus.aagesen at tonica.dk
Wed Apr 29 11:41:57 CEST 2009


Hallo, I am working with the Nut Os  environment.

 

I am developing on AT91sam9260-EK developing kit and the Nut Os environment
is working her, but I am implementing the code in AT91sam9260 chip off board

And her I run into a problem with the ether net configuration, using the
function  NutRegisterDevice(&DEV_ETHER, 0x8300, 5);

I would appreciate  any help on this subject.

 

I have located the problem to "outr(RSTC_CR, RSTC_KEY | RSTC_EXTRST);" in
the code below.

 

This is located in the at91_emac.c file.

 

static int EmacReset(u_long tmo)

{

    u_short phyval;

 

    outr(PMC_PCER, _BV(PIOA_ID));

    outr(PMC_PCER, _BV(PIOB_ID));

    outr(PMC_PCER, _BV(EMAC_ID));

 

    /* Disable TESTMODE and set PHY address 0 and by disabling pull-ups. */

    outr(EMAC_PIO_PUDR,

#if !defined(PHY_MODE_RMII)

        /* Additionally disable RMII, if not configured. */

        _BV(PHY_COL_RMII_BIT) | 

#endif

        _BV(PHY_RXDV_TESTMODE_BIT) | 

        _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |

        _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) |
_BV(PHY_CRS_AD4_BIT));

 

#ifdef PHY_PWRDN_BIT

    /* Disable PHY power down. */

    outr(EMAC_PIO_PER, _BV(PHY_PWRDN_BIT));

    outr(EMAC_PIO_OER, _BV(PHY_PWRDN_BIT));

#ifdef PHY_PWRDN_NEGPOL

    outr(EMAC_PIO_SODR, _BV(PHY_PWRDN_BIT));

#else

    outr(EMAC_PIO_CODR, _BV(PHY_PWRDN_BIT));

#endif

#endif

 

    /* Toggle external hardware reset pin. */

    outr(RSTC_MR, RSTC_KEY | (2 << RSTC_ERSTL_LSB) | RSTC_URSTEN);

    outr(RSTC_CR, RSTC_KEY | RSTC_EXTRST);

    while ((inr(RSTC_SR) & RSTC_NRSTL) == 0);

 

    /* Re-enable pull-ups. */

    outr(EMAC_PIO_PUER, _BV(PHY_RXDV_TESTMODE_BIT) | 

        _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |

        _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) |
_BV(PHY_CRS_AD4_BIT));

 

    /* Configure MII port. */

    outr(EMAC_PIO_ASR, PHY_MII_PINS_A);

    outr(EMAC_PIO_BSR, PHY_MII_PINS_B);

    outr(EMAC_PIO_PDR, PHY_MII_PINS_A | PHY_MII_PINS_B);

 

    /* Enable receive and transmit clocks and set MII mode. */

#ifdef PHY_MODE_RMII

    outr(EMAC_USRIO, EMAC_RMII | EMAC_CLKEN);

#else

    outr(EMAC_USRIO, EMAC_CLKEN);

#endif

 

    /* Enable management port. */

    outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_MPE);

    outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CLK_HCLK_64);

 

    /* Wait for PHY ready. */

    NutDelay(255);

 

#ifndef PHY_MODE_RMII

    /* Clear MII isolate. */

    phy_inw(NIC_PHY_BMCR);

    phy_outw(NIC_PHY_BMCR, phy_inw(NIC_PHY_BMCR) & ~NIC_PHY_BMCR_ISOLATE);

#endif

 

//    /* For some unknown reason it seems to be required to read the ID
registers first. */

//    if (phy_inw(NIC_PHY_ID1) != 0x0181 || (phy_inw(NIC_PHY_ID2) & 0xFFF0)
!= 0xB8A0) {

//        outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);

//        return -1;

//    }

 

// TODO: Make phy id configurable

/* PHY ID */

#define MII_DM9161_ID_H     0x0181

#define MII_DM9161_ID_L     0xb8a0

 

#define MII_AM79C875_ID_H   0x0022

#define MII_AM79C875_ID_L   0x5540      

 

#define MII_MICREL_ID_H     0x0022

#define MII_MICREL_ID_L     0x1610

 

     /* For some unknown reason it seems to be required to read the ID 

registers first. */

 

     // Check for DM PHY (as used on the ATMEL EK)

     if (phy_inw(NIC_PHY_ID1) != MII_DM9161_ID_H ||

        (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_DM9161_ID_L) {

     // Check for MICREL PHY (as used on the Olimex SAM7-EX256)         

         if (phy_inw(NIC_PHY_ID1) != MII_MICREL_ID_H ||

           (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_MICREL_ID_L) {

            outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);

            return -1;

         }

     }

 

 

// TODO: END

 

    /* Handle auto negotiation if configured. */

    phyval = phy_inw(NIC_PHY_BMCR);

    if (phyval & NIC_PHY_BMCR_ANEGENA) {

        /* Wait for auto negotiation completed. */

        phy_inw(NIC_PHY_BMSR);  /* Discard previously latched status. */

        while (--tmo) {

            if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {

                break;

            }

        }

        /* Return error on link timeout. */

        if (tmo == 0) {

            outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);

            return -1;

        }

 

        /*

         * Read link partner abilities and configure EMAC.

         */

        phyval = phy_inw(NIC_PHY_ANLPAR);

        if (phyval & NIC_PHY_ANEG_TX_FDX) {

            /* 100Mb full duplex. */

            outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_SPD | EMAC_FD);

        }

        else if (phyval & NIC_PHY_ANEG_TX_HDX) {

            /* 100Mb half duplex. */

            outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_FD) | EMAC_SPD);

        }

        else if (phyval & NIC_PHY_ANEG_10_FDX) {

            /* 10Mb full duplex. */

            outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_SPD) | EMAC_FD);

        }

        else {

            /* 10Mb half duplex. */

            outr(EMAC_NCFGR, inr(EMAC_NCFGR) & ~(EMAC_SPD | EMAC_FD));

        }

    }

 

    /* Disable management port. */

    outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);

 

    return 0;

}

 

/*

 * NIC interrupt entry.

 */

 

Regards, Rasmus



More information about the En-Nut-Discussion mailing list