From 2bd8e76a705d6a64b853064f6b698706fcd77e43 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 30 Apr 2008 14:58:33 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@279 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- ports/ARM7-AT91SAM7X/mii.h | 4 +++ ports/ARM7-AT91SAM7X/sam7x_emac.c | 51 +++++++++++++++++++++++++++++++++++++-- ports/ARM7-AT91SAM7X/sam7x_emac.h | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/ports/ARM7-AT91SAM7X/mii.h b/ports/ARM7-AT91SAM7X/mii.h index 062d074bc..4ec25667a 100644 --- a/ports/ARM7-AT91SAM7X/mii.h +++ b/ports/ARM7-AT91SAM7X/mii.h @@ -149,4 +149,8 @@ #define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ #define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ +#define MII_DM9161_ID 0x0181b8a0 +#define MII_AM79C875_ID 0x00225540 +#define MII_MICREL_ID 0x00221610 + #endif /* _MII_H_ */ diff --git a/ports/ARM7-AT91SAM7X/sam7x_emac.c b/ports/ARM7-AT91SAM7X/sam7x_emac.c index 5542e74d2..1ffa9b547 100644 --- a/ports/ARM7-AT91SAM7X/sam7x_emac.c +++ b/ports/ARM7-AT91SAM7X/sam7x_emac.c @@ -30,6 +30,7 @@ static uint8_t rbuffers[128 * EMAC_RECEIVE_BUFFERS] __attribute__((aligned(4))); EventSource TransmitDone, ReceiveNotEmpty; +#define PHY_ADDRESS 1 #define AT91C_PB15_ERXDV AT91C_PB15_ERXDV_ECRSDV #define EMAC_PIN_MASK (AT91C_PB1_ETXEN | AT91C_PB2_ETX0 | \ AT91C_PB3_ETX1 | AT91C_PB4_ECRS | \ @@ -41,6 +42,33 @@ EventSource TransmitDone, ReceiveNotEmpty; AT91C_PB15_ERXDV | AT91C_PB16_ECOL | \ AT91C_PB17_ERXCK) +/* + * PHY utilities. + */ +static uint32_t phy_get(uint8_t regno) { + + AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 + (2 << 28) | // RW = 10 + (PHY_ADDRESS << 23) | + (regno << 18) | + (2 << 16); // CODE = 10 + while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) + ; + return AT91C_BASE_EMAC->EMAC_MAN & 0xFFFF; +} + +static void phy_put(uint8_t regno, uint32_t val) { + + AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01 + (1 << 28) | // RW = 01 + (PHY_ADDRESS << 23) | + (regno << 18) | + (2 << 16) | // CODE = 10 + val; + while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE)) + ; +} + /* * EMAC subsystem initialization. */ @@ -84,10 +112,29 @@ void InitEMAC(int prio) { /* * EMAC setup. */ - AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; // Enable Management Port. - AT91C_BASE_EMAC->EMAC_NCFGR |= 2 << 10; // CLK = MCK / 32 + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE; // Enable Management Port + AT91C_BASE_EMAC->EMAC_NCFGR |= 2 << 10; // CLK = MCK / 32 chThdSleep(5); + + (void)phy_get(MII_BMCR); + phy_put(MII_BMCR, phy_get(MII_BMCR) & ~BMCR_ISOLATE); // Disable ISOLATE + + AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; // Disable Management Port + + AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN; // Enable EMAC in MII mode + + +} + +/* + * Set the MAC address. + */ +void EMACSetAddress(uint8_t *eaddr) { + + AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((eaddr[3] << 24) | (eaddr[2] << 16) | + (eaddr[1] << 8) | eaddr[0]); + AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((eaddr[5] << 8) | eaddr[4]); } /* diff --git a/ports/ARM7-AT91SAM7X/sam7x_emac.h b/ports/ARM7-AT91SAM7X/sam7x_emac.h index 6f06d7a02..ede932d05 100644 --- a/ports/ARM7-AT91SAM7X/sam7x_emac.h +++ b/ports/ARM7-AT91SAM7X/sam7x_emac.h @@ -65,6 +65,7 @@ typedef struct { extern "C" { #endif void InitEMAC(int prio); + void EMACSetAddress(uint8_t *eaddr); bool_t EMACTransmit(uint8_t *buf, size_t size); #ifdef __cplusplus } -- cgit v1.2.3