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@151:bde6f7da1755, 2019-07-19 (annotated)
- Committer:
- andrewboyson
- Date:
- Fri Jul 19 17:48:06 2019 +0000
- Revision:
- 151:bde6f7da1755
- Parent:
- 99:962440a00ead
- Child:
- 160:6a1d1d368f80
Removed private key and certificate from semihost storage as found to be unreliable (though secure) and moved it into flash storage (reliable, simple, but visible on mbed.
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 | 99:962440a00ead | 4 | #include "semihost.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 | 99:962440a00ead | 253 | SemihostMac(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 | } |