[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