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