X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Feth_sam3.c;h=686da8baaac1e06c55ff6670a5265a3d5832d11b;hb=577a9116e32fac33614a21b15d8d1443c3ac420b;hp=889a5c1b4ebdc715f58b8ac9930d637029b63532;hpb=72b2dafe03e2095ff62690b809b633024bc49fc4;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/eth_sam3.c b/bertos/cpu/cortex-m3/drv/eth_sam3.c index 889a5c1b..686da8ba 100644 --- a/bertos/cpu/cortex-m3/drv/eth_sam3.c +++ b/bertos/cpu/cortex-m3/drv/eth_sam3.c @@ -141,11 +141,13 @@ static DECLARE_ISR(emac_irqHandler) * * \return Contents of the specified register. */ -static uint16_t phy_hw_read(reg8_t reg) +static uint16_t phy_hw_read(uint8_t phy_addr, reg8_t reg) { // PHY read command. - EMAC_MAN = EMAC_SOF | EMAC_RW_READ | (NIC_PHY_ADDR << EMAC_PHYA_SHIFT) - | ((reg << EMAC_REGA_SHIFT) & EMAC_REGA) | EMAC_CODE; + EMAC_MAN = EMAC_SOF | EMAC_RW_READ + | ((phy_addr << EMAC_PHYA_SHIFT) & EMAC_PHYA) + | ((reg << EMAC_REGA_SHIFT) & EMAC_REGA) + | EMAC_CODE; // Wait until PHY logic completed. while (!(EMAC_NSR & BV(EMAC_IDLE))) @@ -161,11 +163,13 @@ static uint16_t phy_hw_read(reg8_t reg) * \param reg PHY register number. * \param val Value to write. */ -static void phy_hw_write(reg8_t reg, uint16_t val) +static void phy_hw_write(uint8_t phy_addr, reg8_t reg, uint16_t val) { // PHY write command. - EMAC_MAN = EMAC_SOF | EMAC_RW_WRITE | (NIC_PHY_ADDR << EMAC_PHYA_SHIFT) - | ((reg << EMAC_REGA_SHIFT) & EMAC_REGA) | EMAC_CODE | val; + EMAC_MAN = EMAC_SOF | EMAC_RW_WRITE + | ((phy_addr << EMAC_PHYA_SHIFT) & EMAC_PHYA) + | ((reg << EMAC_REGA_SHIFT) & EMAC_REGA) + | EMAC_CODE | val; // Wait until PHY logic completed. while (!(EMAC_NSR & BV(EMAC_IDLE))) @@ -175,26 +179,36 @@ static void phy_hw_write(reg8_t reg, uint16_t val) static int emac_reset(void) { uint16_t phy_cr; + unsigned i; +#if CPU_ARM_AT91 // Enable devices - //PMC_PCER = BV(PIOA_ID); - //PMC_PCER = BV(PIOB_ID); - //PMC_PCER = BV(EMAC_ID); - // TOOD: Implement in sam7x - pmc_periphEnable(PIOA_ID); - pmc_periphEnable(PIOB_ID); - pmc_periphEnable(EMAC_ID); + PMC_PCER = BV(PIOA_ID); + PMC_PCER = BV(PIOB_ID); + PMC_PCER = BV(EMAC_ID); - // Disable TESTMODE + // Disable TESTMODE and RMII PIOB_PUDR = BV(PHY_RXDV_TESTMODE_BIT); -#if CPU_ARM_AT91 - // Disable RMII PIOB_PUDR = BV(PHY_COL_RMII_BIT); // Disable PHY power down. PIOB_PER = BV(PHY_PWRDN_BIT); PIOB_OER = BV(PHY_PWRDN_BIT); PIOB_CODR = BV(PHY_PWRDN_BIT); +#else + pmc_periphEnable(PIOA_ID); + pmc_periphEnable(PIOB_ID); + pmc_periphEnable(PIOC_ID); + pmc_periphEnable(PIOD_ID); + pmc_periphEnable(EMAC_ID); + + // Disable TESTMODE and RMII + PIOC_PUDR = BV(PHY_RXDV_TESTMODE_BIT); + + // Disable PHY power down. + PIOD_PER = BV(PHY_PWRDN_BIT); + PIOD_OER = BV(PHY_PWRDN_BIT); + PIOD_CODR = BV(PHY_PWRDN_BIT); #endif // Toggle external hardware reset pin. @@ -209,18 +223,23 @@ static int emac_reset(void) PIOB_ASR = PHY_MII_PINS; PIOB_BSR = 0; PIOB_PDR = PHY_MII_PINS; + // Enable receive and transmit clocks. EMAC_USRIO = BV(EMAC_CLKEN); #else - PIO_PERIPH_SEL(PIOB_BASE, PHY_MII_PINS, PIO_PERIPH_A); - PIOB_PDR = PHY_MII_PINS; + PIO_PERIPH_SEL(PIOB_BASE, PHY_MII_PINS_PORTB, PIO_PERIPH_A); + PIOB_PDR = PHY_MII_PINS_PORTB; + + PIO_PERIPH_SEL(PIOC_BASE, PHY_MII_PINS_PORTC, PIO_PERIPH_A); + PIOC_PDR = PHY_MII_PINS_PORTC; + // Enable receive, transmit clocks and RMII mode. EMAC_USRIO = BV(EMAC_CLKEN) | BV(EMAC_RMII); #endif // Enable management port. EMAC_NCR |= BV(EMAC_MPE); - EMAC_NCFGR |= EMAC_CLK_HCLK_32; + EMAC_NCFGR |= EMAC_CLK_HCLK_64; // Set local MAC address. EMAC_SA1L = (mac_addr[3] << 24) | (mac_addr[2] << 16) | @@ -228,29 +247,42 @@ static int emac_reset(void) EMAC_SA1H = (mac_addr[5] << 8) | mac_addr[4]; // Wait for PHY ready - timer_delay(255); + timer_delay(500); + +#if 0 // debug test + for (;;) + { + for (i = 0; i < 32; i++) + { + // Clear MII isolate. + phy_hw_read(i, NIC_PHY_BMCR); + phy_cr = phy_hw_read(i, NIC_PHY_BMCR); + + phy_cr &= ~NIC_PHY_BMCR_ISOLATE; + phy_hw_write(i, NIC_PHY_BMCR, phy_cr); + + phy_cr = phy_hw_read(i, NIC_PHY_BMCR); + + LOG_INFO("%s: PHY ID %d %#04x %#04x\n", + __func__, i, + phy_hw_read(i, NIC_PHY_ID1), phy_hw_read(i, NIC_PHY_ID2)); + } + timer_delay(1000); + } +#endif // Clear MII isolate. - phy_hw_read(NIC_PHY_BMCR); - phy_cr = phy_hw_read(NIC_PHY_BMCR); + //phy_hw_read(NIC_PHY_ADDR, NIC_PHY_BMCR); + phy_cr = phy_hw_read(NIC_PHY_ADDR, NIC_PHY_BMCR); phy_cr &= ~NIC_PHY_BMCR_ISOLATE; - phy_hw_write(NIC_PHY_BMCR, phy_cr); + phy_hw_write(NIC_PHY_ADDR, NIC_PHY_BMCR, phy_cr); - phy_cr = phy_hw_read(NIC_PHY_BMCR); + //phy_cr = phy_hw_read(NIC_PHY_ADDR, NIC_PHY_BMCR); LOG_INFO("%s: PHY ID %#04x %#04x\n", __func__, - phy_hw_read(NIC_PHY_ID1), phy_hw_read(NIC_PHY_ID2)); - - // Wait for auto negotiation completed. - phy_hw_read(NIC_PHY_BMSR); - for (;;) - { - if (phy_hw_read(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) - break; - cpu_relax(); - } + phy_hw_read(NIC_PHY_ADDR, NIC_PHY_ID1), phy_hw_read(NIC_PHY_ADDR, NIC_PHY_ID2)); // Disable management port. EMAC_NCR &= ~BV(EMAC_MPE);