A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
link/nic.c@70:74c11fb71a15, 2018-02-16 (annotated)
- Committer:
- andrewboyson
- Date:
- Fri Feb 16 17:31:52 2018 +0000
- Revision:
- 70:74c11fb71a15
- Parent:
- 67:b89a81c6ed99
- Child:
- 99:962440a00ead
Removed need for defs.h
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 60:1d8c7a1e7483 | 1 | #include <stdint.h> |
andrewboyson | 61:aad055f1b0d1 | 2 | |
andrewboyson | 59:e0e556c8bd46 | 3 | #include "nicdefs.h" |
andrewboyson | 60:1d8c7a1e7483 | 4 | #include "nicmac.h" |
andrewboyson | 59:e0e556c8bd46 | 5 | #include "log.h" |
andrewboyson | 59:e0e556c8bd46 | 6 | |
andrewboyson | 61:aad055f1b0d1 | 7 | #define NUM_RX_FRAMES 6 // Number of Rx Frames (== packets) was 3 |
andrewboyson | 61:aad055f1b0d1 | 8 | #define NUM_TX_FRAMES 4 // Number of Tx Frames (== packets) was 2 |
andrewboyson | 59:e0e556c8bd46 | 9 | |
andrewboyson | 59:e0e556c8bd46 | 10 | #define ETH_FRAME_LEN 1536 // Maximum Ethernet Frame Size |
andrewboyson | 61:aad055f1b0d1 | 11 | /* |
andrewboyson | 61:aad055f1b0d1 | 12 | Total length is NUM_RX * ((2 * 4) + (2 * 4) + 0x600) + NUM_TX * ((2 * 4) + (1 * 4) + 0x600) |
andrewboyson | 61:aad055f1b0d1 | 13 | 1 * 1552 1548 |
andrewboyson | 61:aad055f1b0d1 | 14 | |
andrewboyson | 61:aad055f1b0d1 | 15 | Can fit up to 10 in total |
andrewboyson | 61:aad055f1b0d1 | 16 | eg 6 * 1552 + 4 * 1548 = 9312 + 6192 = 15504 |
andrewboyson | 61:aad055f1b0d1 | 17 | */ |
andrewboyson | 61:aad055f1b0d1 | 18 | |
andrewboyson | 61:aad055f1b0d1 | 19 | |
andrewboyson | 61:aad055f1b0d1 | 20 | __attribute__((section("AHBSRAM1"),aligned(4))) static volatile uint8_t r_buff[NUM_RX_FRAMES][ETH_FRAME_LEN]; |
andrewboyson | 61:aad055f1b0d1 | 21 | __attribute__((section("AHBSRAM1"),aligned(4))) static volatile uint8_t t_buff[NUM_TX_FRAMES][ETH_FRAME_LEN]; |
andrewboyson | 61:aad055f1b0d1 | 22 | __attribute__((section("AHBSRAM1"),aligned(4))) static volatile RX_DESC_TypeDef r_desc[NUM_RX_FRAMES]; |
andrewboyson | 61:aad055f1b0d1 | 23 | __attribute__((section("AHBSRAM1"),aligned(8))) static volatile RX_STAT_TypeDef r_stat[NUM_RX_FRAMES]; //Must be aligned on an 8 byte boundary |
andrewboyson | 61:aad055f1b0d1 | 24 | __attribute__((section("AHBSRAM1"),aligned(4))) static volatile TX_DESC_TypeDef t_desc[NUM_TX_FRAMES]; |
andrewboyson | 61:aad055f1b0d1 | 25 | __attribute__((section("AHBSRAM1"),aligned(4))) static volatile TX_STAT_TypeDef t_stat[NUM_TX_FRAMES]; |
andrewboyson | 59:e0e556c8bd46 | 26 | |
andrewboyson | 59:e0e556c8bd46 | 27 | char* NicGetReceivedPacketOrNull(int* pSize) |
andrewboyson | 59:e0e556c8bd46 | 28 | { |
andrewboyson | 70:74c11fb71a15 | 29 | if (RX_PRODUCE_INDEX == RX_CONSUME_INDEX) return NULL; |
andrewboyson | 59:e0e556c8bd46 | 30 | |
andrewboyson | 70:74c11fb71a15 | 31 | uint32_t info = r_stat[RX_CONSUME_INDEX].Info; |
andrewboyson | 59:e0e556c8bd46 | 32 | *pSize = (info & RINFO_SIZE) + 1 - 4; // exclude checksum |
andrewboyson | 59:e0e556c8bd46 | 33 | |
andrewboyson | 70:74c11fb71a15 | 34 | return (char*)r_buff[RX_CONSUME_INDEX]; |
andrewboyson | 59:e0e556c8bd46 | 35 | } |
andrewboyson | 59:e0e556c8bd46 | 36 | void NicReleaseReceivedPacket() |
andrewboyson | 59:e0e556c8bd46 | 37 | { |
andrewboyson | 70:74c11fb71a15 | 38 | if (RX_CONSUME_INDEX == RX_DESCRIPTOR_NUMBER) RX_CONSUME_INDEX = 0; |
andrewboyson | 70:74c11fb71a15 | 39 | else RX_CONSUME_INDEX++; |
andrewboyson | 59:e0e556c8bd46 | 40 | } |
andrewboyson | 59:e0e556c8bd46 | 41 | char* NicGetTransmitPacketOrNull(int* pSize) |
andrewboyson | 59:e0e556c8bd46 | 42 | { |
andrewboyson | 70:74c11fb71a15 | 43 | if (TX_CONSUME_INDEX == 0 && TX_PRODUCE_INDEX == TX_DESCRIPTOR_NUMBER) return NULL; |
andrewboyson | 70:74c11fb71a15 | 44 | if (TX_PRODUCE_INDEX == TX_CONSUME_INDEX - 1) return NULL; |
andrewboyson | 59:e0e556c8bd46 | 45 | *pSize = ETH_FRAME_LEN - 4; |
andrewboyson | 70:74c11fb71a15 | 46 | return (char*)t_buff[TX_PRODUCE_INDEX]; |
andrewboyson | 59:e0e556c8bd46 | 47 | } |
andrewboyson | 59:e0e556c8bd46 | 48 | void NicSendTransmitPacket(int size) |
andrewboyson | 59:e0e556c8bd46 | 49 | { |
andrewboyson | 59:e0e556c8bd46 | 50 | if (size == 0) return; |
andrewboyson | 70:74c11fb71a15 | 51 | t_desc[TX_PRODUCE_INDEX].Ctrl = (size - 1) | (TCTRL_INT | TCTRL_LAST); |
andrewboyson | 70:74c11fb71a15 | 52 | if (TX_PRODUCE_INDEX == TX_DESCRIPTOR_NUMBER) TX_PRODUCE_INDEX = 0; |
andrewboyson | 70:74c11fb71a15 | 53 | else TX_PRODUCE_INDEX++; |
andrewboyson | 59:e0e556c8bd46 | 54 | } |
andrewboyson | 59:e0e556c8bd46 | 55 | |
andrewboyson | 59:e0e556c8bd46 | 56 | static void txdscr_init() |
andrewboyson | 59:e0e556c8bd46 | 57 | { |
andrewboyson | 59:e0e556c8bd46 | 58 | int i; |
andrewboyson | 59:e0e556c8bd46 | 59 | |
andrewboyson | 59:e0e556c8bd46 | 60 | for(i = 0; i < NUM_TX_FRAMES; i++) |
andrewboyson | 59:e0e556c8bd46 | 61 | { |
andrewboyson | 59:e0e556c8bd46 | 62 | t_desc[i].Packet = (uint32_t)&t_buff[i]; |
andrewboyson | 59:e0e556c8bd46 | 63 | t_desc[i].Ctrl = 0; |
andrewboyson | 59:e0e556c8bd46 | 64 | t_stat[i].Info = 0; |
andrewboyson | 59:e0e556c8bd46 | 65 | } |
andrewboyson | 59:e0e556c8bd46 | 66 | |
andrewboyson | 70:74c11fb71a15 | 67 | TX_DESCRIPTOR = (uint32_t)t_desc; /* Set EMAC Transmit Descriptor Registers. */ |
andrewboyson | 70:74c11fb71a15 | 68 | TX_STATUS = (uint32_t)t_stat; |
andrewboyson | 70:74c11fb71a15 | 69 | TX_DESCRIPTOR_NUMBER = NUM_TX_FRAMES - 1; |
andrewboyson | 59:e0e556c8bd46 | 70 | |
andrewboyson | 70:74c11fb71a15 | 71 | TX_PRODUCE_INDEX = 0; /* Tx Descriptors Point to 0 */ |
andrewboyson | 59:e0e556c8bd46 | 72 | } |
andrewboyson | 59:e0e556c8bd46 | 73 | |
andrewboyson | 59:e0e556c8bd46 | 74 | static void rxdscr_init() |
andrewboyson | 59:e0e556c8bd46 | 75 | { |
andrewboyson | 59:e0e556c8bd46 | 76 | int i; |
andrewboyson | 59:e0e556c8bd46 | 77 | |
andrewboyson | 59:e0e556c8bd46 | 78 | for(i = 0; i < NUM_RX_FRAMES; i++) |
andrewboyson | 59:e0e556c8bd46 | 79 | { |
andrewboyson | 59:e0e556c8bd46 | 80 | r_desc[i].Packet = (uint32_t)&r_buff[i]; |
andrewboyson | 59:e0e556c8bd46 | 81 | r_desc[i].Ctrl = RCTRL_INT | (ETH_FRAME_LEN-1); |
andrewboyson | 59:e0e556c8bd46 | 82 | r_stat[i].Info = 0; |
andrewboyson | 59:e0e556c8bd46 | 83 | r_stat[i].HashCRC = 0; |
andrewboyson | 59:e0e556c8bd46 | 84 | } |
andrewboyson | 59:e0e556c8bd46 | 85 | |
andrewboyson | 70:74c11fb71a15 | 86 | RX_DESCRIPTOR = (uint32_t)r_desc; /* Set EMAC Receive Descriptor Registers. */ |
andrewboyson | 70:74c11fb71a15 | 87 | RX_STATUS = (uint32_t)r_stat; //Must be aligned on an 8 byte boundary |
andrewboyson | 70:74c11fb71a15 | 88 | RX_DESCRIPTOR_NUMBER = NUM_RX_FRAMES - 1; |
andrewboyson | 59:e0e556c8bd46 | 89 | |
andrewboyson | 70:74c11fb71a15 | 90 | RX_CONSUME_INDEX = 0; /* Rx Descriptors Point to 0 */ |
andrewboyson | 59:e0e556c8bd46 | 91 | } |
andrewboyson | 59:e0e556c8bd46 | 92 | static int phy_write(unsigned int PhyReg, unsigned short Data) |
andrewboyson | 59:e0e556c8bd46 | 93 | { |
andrewboyson | 59:e0e556c8bd46 | 94 | unsigned int timeOut; |
andrewboyson | 59:e0e556c8bd46 | 95 | |
andrewboyson | 70:74c11fb71a15 | 96 | MADR = DP83848C_DEF_ADR | PhyReg; |
andrewboyson | 70:74c11fb71a15 | 97 | MWTD = Data; |
andrewboyson | 59:e0e556c8bd46 | 98 | |
andrewboyson | 59:e0e556c8bd46 | 99 | // Wait until operation completed |
andrewboyson | 59:e0e556c8bd46 | 100 | for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) |
andrewboyson | 59:e0e556c8bd46 | 101 | { |
andrewboyson | 70:74c11fb71a15 | 102 | if((MIND & MIND_BUSY) == 0) return 0; |
andrewboyson | 59:e0e556c8bd46 | 103 | } |
andrewboyson | 59:e0e556c8bd46 | 104 | |
andrewboyson | 59:e0e556c8bd46 | 105 | //Timed out |
andrewboyson | 59:e0e556c8bd46 | 106 | return -1; |
andrewboyson | 59:e0e556c8bd46 | 107 | } |
andrewboyson | 59:e0e556c8bd46 | 108 | |
andrewboyson | 59:e0e556c8bd46 | 109 | static int phy_read(unsigned int PhyReg) |
andrewboyson | 59:e0e556c8bd46 | 110 | { |
andrewboyson | 59:e0e556c8bd46 | 111 | unsigned int timeOut; |
andrewboyson | 59:e0e556c8bd46 | 112 | |
andrewboyson | 70:74c11fb71a15 | 113 | MADR = DP83848C_DEF_ADR | PhyReg; |
andrewboyson | 70:74c11fb71a15 | 114 | MCMD = MCMD_READ; |
andrewboyson | 59:e0e556c8bd46 | 115 | |
andrewboyson | 59:e0e556c8bd46 | 116 | // Wait until operation completed |
andrewboyson | 59:e0e556c8bd46 | 117 | for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) |
andrewboyson | 59:e0e556c8bd46 | 118 | { |
andrewboyson | 70:74c11fb71a15 | 119 | if((MIND & MIND_BUSY) == 0) |
andrewboyson | 59:e0e556c8bd46 | 120 | { |
andrewboyson | 70:74c11fb71a15 | 121 | MCMD = 0; |
andrewboyson | 70:74c11fb71a15 | 122 | return MRDD; // Return a 16-bit value. |
andrewboyson | 59:e0e556c8bd46 | 123 | } |
andrewboyson | 59:e0e556c8bd46 | 124 | } |
andrewboyson | 59:e0e556c8bd46 | 125 | return -1; |
andrewboyson | 59:e0e556c8bd46 | 126 | } |
andrewboyson | 59:e0e556c8bd46 | 127 | |
andrewboyson | 59:e0e556c8bd46 | 128 | void NicLinkAddress(char *mac) |
andrewboyson | 59:e0e556c8bd46 | 129 | { |
andrewboyson | 70:74c11fb71a15 | 130 | mac[5] = SA0 >> 8; |
andrewboyson | 70:74c11fb71a15 | 131 | mac[4] = SA0 & 0xFF; |
andrewboyson | 70:74c11fb71a15 | 132 | mac[3] = SA1 >> 8; |
andrewboyson | 70:74c11fb71a15 | 133 | mac[2] = SA1 & 0xFF; |
andrewboyson | 70:74c11fb71a15 | 134 | mac[1] = SA2 >> 8; |
andrewboyson | 70:74c11fb71a15 | 135 | mac[0] = SA2 & 0xFF; |
andrewboyson | 59:e0e556c8bd46 | 136 | } |
andrewboyson | 59:e0e556c8bd46 | 137 | |
andrewboyson | 59:e0e556c8bd46 | 138 | void NicLinkSetSpeedDuplex(int speed, int duplex) |
andrewboyson | 59:e0e556c8bd46 | 139 | { |
andrewboyson | 59:e0e556c8bd46 | 140 | unsigned short phy_data; |
andrewboyson | 59:e0e556c8bd46 | 141 | int tout; |
andrewboyson | 59:e0e556c8bd46 | 142 | |
andrewboyson | 59:e0e556c8bd46 | 143 | if((speed < 0) || (speed > 1)) phy_data = PHY_AUTO_NEG; |
andrewboyson | 59:e0e556c8bd46 | 144 | else phy_data = (((unsigned short) speed << 13) | ((unsigned short) duplex << 8)); |
andrewboyson | 59:e0e556c8bd46 | 145 | |
andrewboyson | 59:e0e556c8bd46 | 146 | phy_write(PHY_REG_BMCR, phy_data); |
andrewboyson | 59:e0e556c8bd46 | 147 | |
andrewboyson | 61:aad055f1b0d1 | 148 | for(tout = 100; tout; tout--) __nop(); /* A short delay */ |
andrewboyson | 59:e0e556c8bd46 | 149 | |
andrewboyson | 59:e0e556c8bd46 | 150 | phy_data = phy_read(PHY_REG_STS); |
andrewboyson | 59:e0e556c8bd46 | 151 | |
andrewboyson | 59:e0e556c8bd46 | 152 | if(phy_data & PHY_STS_DUPLEX) |
andrewboyson | 59:e0e556c8bd46 | 153 | { |
andrewboyson | 70:74c11fb71a15 | 154 | MAC2 |= MAC2_FULL_DUP; |
andrewboyson | 70:74c11fb71a15 | 155 | COMMAND |= CR_FULL_DUP; |
andrewboyson | 70:74c11fb71a15 | 156 | IPGT = IPGT_FULL_DUP; |
andrewboyson | 59:e0e556c8bd46 | 157 | } |
andrewboyson | 59:e0e556c8bd46 | 158 | else |
andrewboyson | 59:e0e556c8bd46 | 159 | { |
andrewboyson | 70:74c11fb71a15 | 160 | MAC2 &= ~MAC2_FULL_DUP; |
andrewboyson | 70:74c11fb71a15 | 161 | COMMAND &= ~CR_FULL_DUP; |
andrewboyson | 70:74c11fb71a15 | 162 | IPGT = IPGT_HALF_DUP; |
andrewboyson | 59:e0e556c8bd46 | 163 | } |
andrewboyson | 59:e0e556c8bd46 | 164 | |
andrewboyson | 59:e0e556c8bd46 | 165 | if(phy_data & PHY_STS_SPEED) |
andrewboyson | 59:e0e556c8bd46 | 166 | { |
andrewboyson | 70:74c11fb71a15 | 167 | SUPP &= ~SUPP_SPEED; |
andrewboyson | 59:e0e556c8bd46 | 168 | } |
andrewboyson | 59:e0e556c8bd46 | 169 | else |
andrewboyson | 59:e0e556c8bd46 | 170 | { |
andrewboyson | 70:74c11fb71a15 | 171 | SUPP |= SUPP_SPEED; |
andrewboyson | 59:e0e556c8bd46 | 172 | } |
andrewboyson | 59:e0e556c8bd46 | 173 | } |
andrewboyson | 59:e0e556c8bd46 | 174 | |
andrewboyson | 59:e0e556c8bd46 | 175 | int NicLinkIsUp(void) |
andrewboyson | 59:e0e556c8bd46 | 176 | { |
andrewboyson | 59:e0e556c8bd46 | 177 | return (phy_read(PHY_REG_STS) & PHY_STS_LINK); |
andrewboyson | 59:e0e556c8bd46 | 178 | } |
andrewboyson | 59:e0e556c8bd46 | 179 | static int phy_reset() |
andrewboyson | 59:e0e556c8bd46 | 180 | { |
andrewboyson | 59:e0e556c8bd46 | 181 | int regv, tout; |
andrewboyson | 59:e0e556c8bd46 | 182 | |
andrewboyson | 59:e0e556c8bd46 | 183 | // perform PHY reset |
andrewboyson | 59:e0e556c8bd46 | 184 | phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); |
andrewboyson | 59:e0e556c8bd46 | 185 | |
andrewboyson | 59:e0e556c8bd46 | 186 | // Wait for hardware reset to end. |
andrewboyson | 59:e0e556c8bd46 | 187 | for(tout = 0x20000; ; tout--) |
andrewboyson | 59:e0e556c8bd46 | 188 | { |
andrewboyson | 59:e0e556c8bd46 | 189 | regv = phy_read(PHY_REG_BMCR); |
andrewboyson | 59:e0e556c8bd46 | 190 | if(regv < 0 || tout == 0) return -1; // Error |
andrewboyson | 59:e0e556c8bd46 | 191 | if(!(regv & PHY_BMCR_RESET)) break; // Reset complete. |
andrewboyson | 59:e0e556c8bd46 | 192 | } |
andrewboyson | 59:e0e556c8bd46 | 193 | uint32_t phy_id = (phy_read(PHY_REG_IDR1) << 16); |
andrewboyson | 59:e0e556c8bd46 | 194 | phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); |
andrewboyson | 59:e0e556c8bd46 | 195 | |
andrewboyson | 59:e0e556c8bd46 | 196 | //Check is the right PHY |
andrewboyson | 59:e0e556c8bd46 | 197 | if (phy_id != DP83848C_ID) |
andrewboyson | 59:e0e556c8bd46 | 198 | { |
andrewboyson | 60:1d8c7a1e7483 | 199 | LogTimeF("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); |
andrewboyson | 59:e0e556c8bd46 | 200 | return -1; |
andrewboyson | 59:e0e556c8bd46 | 201 | } |
andrewboyson | 59:e0e556c8bd46 | 202 | return 0; |
andrewboyson | 59:e0e556c8bd46 | 203 | } |
andrewboyson | 59:e0e556c8bd46 | 204 | int NicInit() |
andrewboyson | 59:e0e556c8bd46 | 205 | { |
andrewboyson | 59:e0e556c8bd46 | 206 | int tout; |
andrewboyson | 59:e0e556c8bd46 | 207 | char mac[6]; |
andrewboyson | 59:e0e556c8bd46 | 208 | unsigned int clock = 10; //96,000,000 |
andrewboyson | 59:e0e556c8bd46 | 209 | |
andrewboyson | 59:e0e556c8bd46 | 210 | // Reset all EMAC internal modules. |
andrewboyson | 70:74c11fb71a15 | 211 | MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; |
andrewboyson | 70:74c11fb71a15 | 212 | COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; |
andrewboyson | 59:e0e556c8bd46 | 213 | |
andrewboyson | 59:e0e556c8bd46 | 214 | // A short delay after reset. |
andrewboyson | 61:aad055f1b0d1 | 215 | for(tout = 100; tout; tout--) __nop(); |
andrewboyson | 59:e0e556c8bd46 | 216 | |
andrewboyson | 59:e0e556c8bd46 | 217 | // Initialize MAC control registers. |
andrewboyson | 70:74c11fb71a15 | 218 | MAC1 = MAC1_PASS_ALL; |
andrewboyson | 70:74c11fb71a15 | 219 | MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; |
andrewboyson | 70:74c11fb71a15 | 220 | MAXF = ETH_FRAME_LEN; |
andrewboyson | 70:74c11fb71a15 | 221 | CLRT = CLRT_DEF; |
andrewboyson | 70:74c11fb71a15 | 222 | IPGR = IPGR_DEF; |
andrewboyson | 59:e0e556c8bd46 | 223 | |
andrewboyson | 59:e0e556c8bd46 | 224 | // Enable Reduced MII interface. |
andrewboyson | 70:74c11fb71a15 | 225 | COMMAND = CR_RMII | CR_PASS_RUNT_FRM; |
andrewboyson | 59:e0e556c8bd46 | 226 | |
andrewboyson | 59:e0e556c8bd46 | 227 | // Set clock and reset |
andrewboyson | 70:74c11fb71a15 | 228 | MCFG = (clock << 0x2) & MCFG_CLK_SEL; |
andrewboyson | 70:74c11fb71a15 | 229 | MCFG |= MCFG_RES_MII; |
andrewboyson | 59:e0e556c8bd46 | 230 | |
andrewboyson | 59:e0e556c8bd46 | 231 | // A short delay after reset |
andrewboyson | 61:aad055f1b0d1 | 232 | for(tout = 100; tout; tout--) __nop(); |
andrewboyson | 59:e0e556c8bd46 | 233 | |
andrewboyson | 59:e0e556c8bd46 | 234 | // Set clock |
andrewboyson | 70:74c11fb71a15 | 235 | MCFG = (clock << 0x2) & MCFG_CLK_SEL; |
andrewboyson | 70:74c11fb71a15 | 236 | MCMD = 0; |
andrewboyson | 59:e0e556c8bd46 | 237 | |
andrewboyson | 59:e0e556c8bd46 | 238 | // Reset Reduced MII Logic. |
andrewboyson | 70:74c11fb71a15 | 239 | SUPP = SUPP_RES_RMII; |
andrewboyson | 59:e0e556c8bd46 | 240 | |
andrewboyson | 59:e0e556c8bd46 | 241 | // A short delay |
andrewboyson | 61:aad055f1b0d1 | 242 | for (tout = 100; tout; tout--) __nop(); |
andrewboyson | 59:e0e556c8bd46 | 243 | |
andrewboyson | 70:74c11fb71a15 | 244 | SUPP = 0; |
andrewboyson | 59:e0e556c8bd46 | 245 | |
andrewboyson | 59:e0e556c8bd46 | 246 | //Reset the PHY |
andrewboyson | 59:e0e556c8bd46 | 247 | if (phy_reset()) return -1; |
andrewboyson | 59:e0e556c8bd46 | 248 | |
andrewboyson | 59:e0e556c8bd46 | 249 | //Set the link to auto negotiate |
andrewboyson | 59:e0e556c8bd46 | 250 | NicLinkSetSpeedDuplex(-1, 0); |
andrewboyson | 59:e0e556c8bd46 | 251 | |
andrewboyson | 59:e0e556c8bd46 | 252 | // Set the Ethernet MAC Address registers |
andrewboyson | 60:1d8c7a1e7483 | 253 | NicMac(mac); |
andrewboyson | 70:74c11fb71a15 | 254 | SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4]; |
andrewboyson | 70:74c11fb71a15 | 255 | SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2]; |
andrewboyson | 70:74c11fb71a15 | 256 | SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0]; |
andrewboyson | 59:e0e556c8bd46 | 257 | |
andrewboyson | 59:e0e556c8bd46 | 258 | //Initialise DMA descriptors |
andrewboyson | 59:e0e556c8bd46 | 259 | txdscr_init(); |
andrewboyson | 59:e0e556c8bd46 | 260 | rxdscr_init(); |
andrewboyson | 59:e0e556c8bd46 | 261 | |
andrewboyson | 59:e0e556c8bd46 | 262 | // Set filter |
andrewboyson | 70:74c11fb71a15 | 263 | RX_FILTER_CTRL = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; |
andrewboyson | 59:e0e556c8bd46 | 264 | |
andrewboyson | 59:e0e556c8bd46 | 265 | // Disable and clear EMAC interrupts |
andrewboyson | 70:74c11fb71a15 | 266 | INT_ENABLE = 0; |
andrewboyson | 70:74c11fb71a15 | 267 | INT_CLEAR = 0xFFFF; |
andrewboyson | 59:e0e556c8bd46 | 268 | |
andrewboyson | 59:e0e556c8bd46 | 269 | //Enable receive and transmit |
andrewboyson | 70:74c11fb71a15 | 270 | COMMAND |= (CR_RX_EN | CR_TX_EN); |
andrewboyson | 70:74c11fb71a15 | 271 | MAC1 |= MAC1_REC_EN; |
andrewboyson | 59:e0e556c8bd46 | 272 | |
andrewboyson | 59:e0e556c8bd46 | 273 | //Return success |
andrewboyson | 59:e0e556c8bd46 | 274 | return 0; |
andrewboyson | 59:e0e556c8bd46 | 275 | } |