diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-04-30 14:58:33 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-04-30 14:58:33 +0000 |
commit | 2bd8e76a705d6a64b853064f6b698706fcd77e43 (patch) | |
tree | 9ad5b39d175122b73834a0ae1bc9fe29716c318b | |
parent | 2f94eac8102294109febd5e34655cb2cd2a5e201 (diff) | |
download | ChibiOS-2bd8e76a705d6a64b853064f6b698706fcd77e43.tar.gz ChibiOS-2bd8e76a705d6a64b853064f6b698706fcd77e43.tar.bz2 ChibiOS-2bd8e76a705d6a64b853064f6b698706fcd77e43.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@279 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r-- | ports/ARM7-AT91SAM7X/mii.h | 4 | ||||
-rw-r--r-- | ports/ARM7-AT91SAM7X/sam7x_emac.c | 51 | ||||
-rw-r--r-- | 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 | \
@@ -42,6 +43,33 @@ EventSource TransmitDone, ReceiveNotEmpty; 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.
*/
void InitEMAC(int prio) {
@@ -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
}
|