Webserver basic for CDU
Dependencies: mbed
Fork of EasyWebCR by
ethmac.c@0:12b53511e212, 2010-01-29 (annotated)
- Committer:
- igorsk
- Date:
- Fri Jan 29 21:46:31 2010 +0000
- Revision:
- 0:12b53511e212
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igorsk | 0:12b53511e212 | 1 | /****************************************************************** |
igorsk | 0:12b53511e212 | 2 | ***** ***** |
igorsk | 0:12b53511e212 | 3 | ***** Name: cs8900.c ***** |
igorsk | 0:12b53511e212 | 4 | ***** Ver.: 1.0 ***** |
igorsk | 0:12b53511e212 | 5 | ***** Date: 07/05/2001 ***** |
igorsk | 0:12b53511e212 | 6 | ***** Auth: Andreas Dannenberg ***** |
igorsk | 0:12b53511e212 | 7 | ***** HTWK Leipzig ***** |
igorsk | 0:12b53511e212 | 8 | ***** university of applied sciences ***** |
igorsk | 0:12b53511e212 | 9 | ***** Germany ***** |
igorsk | 0:12b53511e212 | 10 | ***** adannenb@et.htwk-leipzig.de ***** |
igorsk | 0:12b53511e212 | 11 | ***** Func: ethernet packet-driver for use with LAN- ***** |
igorsk | 0:12b53511e212 | 12 | ***** controller CS8900 from Crystal/Cirrus Logic ***** |
igorsk | 0:12b53511e212 | 13 | ***** ***** |
igorsk | 0:12b53511e212 | 14 | ******************************************************************/ |
igorsk | 0:12b53511e212 | 15 | |
igorsk | 0:12b53511e212 | 16 | // Modifications by Code Red Technologies for NXP LPC1776 |
igorsk | 0:12b53511e212 | 17 | // Filename changed to ethmac.c as no longer for cs8900 |
igorsk | 0:12b53511e212 | 18 | |
igorsk | 0:12b53511e212 | 19 | // CodeRed - updated include to match new filename |
igorsk | 0:12b53511e212 | 20 | |
igorsk | 0:12b53511e212 | 21 | #include "mbed.h" |
igorsk | 0:12b53511e212 | 22 | |
igorsk | 0:12b53511e212 | 23 | #include "ethmac.h" |
igorsk | 0:12b53511e212 | 24 | |
igorsk | 0:12b53511e212 | 25 | // CodeRed - add additional includes |
igorsk | 0:12b53511e212 | 26 | #include "tcpip.h" |
igorsk | 0:12b53511e212 | 27 | |
igorsk | 0:12b53511e212 | 28 | |
igorsk | 0:12b53511e212 | 29 | // CodeRed - new static pointers for receive and transmit |
igorsk | 0:12b53511e212 | 30 | static unsigned short *rxptr; |
igorsk | 0:12b53511e212 | 31 | static unsigned short *txptr; |
igorsk | 0:12b53511e212 | 32 | |
igorsk | 0:12b53511e212 | 33 | // CodeRed - function added to write to external ethernet PHY chip |
igorsk | 0:12b53511e212 | 34 | void WriteToPHY (int reg, int writeval) |
igorsk | 0:12b53511e212 | 35 | { |
igorsk | 0:12b53511e212 | 36 | unsigned int loop; |
igorsk | 0:12b53511e212 | 37 | // Set up address to access in MII Mgmt Address Register |
igorsk | 0:12b53511e212 | 38 | LPC_EMAC->MADR = DP83848C_DEF_ADR | reg; |
igorsk | 0:12b53511e212 | 39 | // Write value into MII Mgmt Write Data Register |
igorsk | 0:12b53511e212 | 40 | LPC_EMAC->MWTD = writeval; |
igorsk | 0:12b53511e212 | 41 | // Loop whilst write to PHY completes |
igorsk | 0:12b53511e212 | 42 | for (loop = 0; loop < MII_WR_TOUT; loop++) { |
igorsk | 0:12b53511e212 | 43 | if ((LPC_EMAC->MIND & MIND_BUSY) == 0) { break; } |
igorsk | 0:12b53511e212 | 44 | } |
igorsk | 0:12b53511e212 | 45 | } |
igorsk | 0:12b53511e212 | 46 | |
igorsk | 0:12b53511e212 | 47 | // CodeRed - function added to read from external ethernet PHY chip |
igorsk | 0:12b53511e212 | 48 | unsigned short ReadFromPHY (unsigned char reg) |
igorsk | 0:12b53511e212 | 49 | { |
igorsk | 0:12b53511e212 | 50 | unsigned int loop; |
igorsk | 0:12b53511e212 | 51 | // Set up address to access in MII Mgmt Address Register |
igorsk | 0:12b53511e212 | 52 | LPC_EMAC->MADR = DP83848C_DEF_ADR | reg; |
igorsk | 0:12b53511e212 | 53 | // Trigger a PHY read via MII Mgmt Command Register |
igorsk | 0:12b53511e212 | 54 | LPC_EMAC->MCMD = MCMD_READ; |
igorsk | 0:12b53511e212 | 55 | // Loop whilst read from PHY completes |
igorsk | 0:12b53511e212 | 56 | for (loop = 0; loop < MII_RD_TOUT; loop++) { |
igorsk | 0:12b53511e212 | 57 | if ((LPC_EMAC->MIND & MIND_BUSY) == 0) { break; } |
igorsk | 0:12b53511e212 | 58 | } |
igorsk | 0:12b53511e212 | 59 | LPC_EMAC->MCMD = 0; // Cancel read |
igorsk | 0:12b53511e212 | 60 | // Returned value is in MII Mgmt Read Data Register |
igorsk | 0:12b53511e212 | 61 | return (LPC_EMAC->MRDD); |
igorsk | 0:12b53511e212 | 62 | } |
igorsk | 0:12b53511e212 | 63 | |
igorsk | 0:12b53511e212 | 64 | |
igorsk | 0:12b53511e212 | 65 | |
igorsk | 0:12b53511e212 | 66 | // CodeRed - Init8900() replaced by Init_EthMAC() |
igorsk | 0:12b53511e212 | 67 | /* |
igorsk | 0:12b53511e212 | 68 | // configure port-pins for use with LAN-controller, |
igorsk | 0:12b53511e212 | 69 | // reset it and send the configuration-sequence |
igorsk | 0:12b53511e212 | 70 | // (InitSeq[]) |
igorsk | 0:12b53511e212 | 71 | |
igorsk | 0:12b53511e212 | 72 | void Init8900(void) |
igorsk | 0:12b53511e212 | 73 | { |
igorsk | 0:12b53511e212 | 74 | unsigned int i; |
igorsk | 0:12b53511e212 | 75 | |
igorsk | 0:12b53511e212 | 76 | P3SEL = 0x30; // reserve P3.4 and P3.5 for rs232 |
igorsk | 0:12b53511e212 | 77 | P3OUT = IOR | IOW; // reset outputs, control lines high |
igorsk | 0:12b53511e212 | 78 | P3DIR = 0xFF; // port 3 as output (all pins but rs232) |
igorsk | 0:12b53511e212 | 79 | |
igorsk | 0:12b53511e212 | 80 | P5SEL = 0; // select standard port functions |
igorsk | 0:12b53511e212 | 81 | P5OUT = 0; // reset outputs |
igorsk | 0:12b53511e212 | 82 | P5DIR = 0xFF; // switch data port to output |
igorsk | 0:12b53511e212 | 83 | |
igorsk | 0:12b53511e212 | 84 | Write8900(ADD_PORT, PP_SelfCTL); |
igorsk | 0:12b53511e212 | 85 | Write8900(DATA_PORT, POWER_ON_RESET); // Reset the Ethernet-Controller |
igorsk | 0:12b53511e212 | 86 | |
igorsk | 0:12b53511e212 | 87 | Write8900(ADD_PORT, PP_SelfST); |
igorsk | 0:12b53511e212 | 88 | while (!(Read8900(DATA_PORT) & INIT_DONE)); // wait until chip-reset is done |
igorsk | 0:12b53511e212 | 89 | |
igorsk | 0:12b53511e212 | 90 | for (i = 0; i < sizeof InitSeq / sizeof (TInitSeq); i++) // configure the CS8900 |
igorsk | 0:12b53511e212 | 91 | { |
igorsk | 0:12b53511e212 | 92 | Write8900(ADD_PORT, InitSeq[i].Addr); |
igorsk | 0:12b53511e212 | 93 | Write8900(DATA_PORT, InitSeq[i].Data); |
igorsk | 0:12b53511e212 | 94 | } |
igorsk | 0:12b53511e212 | 95 | } |
igorsk | 0:12b53511e212 | 96 | */ |
igorsk | 0:12b53511e212 | 97 | |
igorsk | 0:12b53511e212 | 98 | // Ethernet power/clock control bit in PCONP register |
igorsk | 0:12b53511e212 | 99 | #define PCENET 0x40000000 |
igorsk | 0:12b53511e212 | 100 | // Ethernet configuration for PINSEL2, as per user guide section 5.3 |
igorsk | 0:12b53511e212 | 101 | #define ENET_PINSEL2_CONFIG 0x50150105 |
igorsk | 0:12b53511e212 | 102 | // Ethernet configuration for PINSEL3, as per user guide section 5.4 |
igorsk | 0:12b53511e212 | 103 | #define ENET_PINSEL3_CONFIG 0x00000005 |
igorsk | 0:12b53511e212 | 104 | // Only bottom byte of PINSEL3 relevant to Ethernet |
igorsk | 0:12b53511e212 | 105 | #define ENET_PINSEL3_MASK 0x0000000F |
igorsk | 0:12b53511e212 | 106 | |
igorsk | 0:12b53511e212 | 107 | void Init_EthMAC(void) |
igorsk | 0:12b53511e212 | 108 | { |
igorsk | 0:12b53511e212 | 109 | unsigned int loop, value, phyid1, phyid2; |
igorsk | 0:12b53511e212 | 110 | |
igorsk | 0:12b53511e212 | 111 | unsigned phy_in_use = 0; |
igorsk | 0:12b53511e212 | 112 | unsigned phy_linkstatus_reg; |
igorsk | 0:12b53511e212 | 113 | unsigned phy_linkstatus_mask; |
igorsk | 0:12b53511e212 | 114 | |
igorsk | 0:12b53511e212 | 115 | // Set Ethernet power/clock control bit |
igorsk | 0:12b53511e212 | 116 | LPC_SC->PCONP |= PCENET; |
igorsk | 0:12b53511e212 | 117 | |
igorsk | 0:12b53511e212 | 118 | //Enable Ethernet pins through PINSEL registers |
igorsk | 0:12b53511e212 | 119 | LPC_PINCON->PINSEL2 = ENET_PINSEL2_CONFIG; |
igorsk | 0:12b53511e212 | 120 | LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~(ENET_PINSEL3_MASK)) | ENET_PINSEL3_CONFIG; |
igorsk | 0:12b53511e212 | 121 | |
igorsk | 0:12b53511e212 | 122 | // Set up MAC Configuration Register 1 |
igorsk | 0:12b53511e212 | 123 | LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | |
igorsk | 0:12b53511e212 | 124 | MAC1_RES_MCS_RX |MAC1_SIM_RES | MAC1_SOFT_RES; |
igorsk | 0:12b53511e212 | 125 | |
igorsk | 0:12b53511e212 | 126 | // Set up MAC Command Register |
igorsk | 0:12b53511e212 | 127 | LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; |
igorsk | 0:12b53511e212 | 128 | |
igorsk | 0:12b53511e212 | 129 | // Short delay |
igorsk | 0:12b53511e212 | 130 | for (loop = 100; loop; loop--); |
igorsk | 0:12b53511e212 | 131 | |
igorsk | 0:12b53511e212 | 132 | // Set up MAC Configuration Register 1 to pass all receive frames |
igorsk | 0:12b53511e212 | 133 | LPC_EMAC->MAC1 = MAC1_PASS_ALL; |
igorsk | 0:12b53511e212 | 134 | // Set up MAC Configuration Register 2 to append CRC and pad out frames |
igorsk | 0:12b53511e212 | 135 | LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; |
igorsk | 0:12b53511e212 | 136 | |
igorsk | 0:12b53511e212 | 137 | // Set Ethernet Maximum Frame Register |
igorsk | 0:12b53511e212 | 138 | LPC_EMAC->MAXF = ETH_MAX_FLEN; |
igorsk | 0:12b53511e212 | 139 | // Set Collision Window / Retry Register |
igorsk | 0:12b53511e212 | 140 | LPC_EMAC->CLRT = CLRT_DEF; |
igorsk | 0:12b53511e212 | 141 | // Set Non Back-to-Back Inter-Packet-Gap Register |
igorsk | 0:12b53511e212 | 142 | LPC_EMAC->IPGR = IPGR_DEF; |
igorsk | 0:12b53511e212 | 143 | |
igorsk | 0:12b53511e212 | 144 | // Set MAC Command Register to enable Reduced MII interface |
igorsk | 0:12b53511e212 | 145 | // and prevent runt frames being filtered out |
igorsk | 0:12b53511e212 | 146 | LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; |
igorsk | 0:12b53511e212 | 147 | |
igorsk | 0:12b53511e212 | 148 | |
igorsk | 0:12b53511e212 | 149 | // Put DP83848C PHY into reset mode |
igorsk | 0:12b53511e212 | 150 | WriteToPHY (PHY_REG_BMCR, 0x8000); |
igorsk | 0:12b53511e212 | 151 | |
igorsk | 0:12b53511e212 | 152 | // Loop until hardware reset completes |
igorsk | 0:12b53511e212 | 153 | for (loop = 0; loop < 0x100000; loop++) { |
igorsk | 0:12b53511e212 | 154 | value = ReadFromPHY (PHY_REG_BMCR); |
igorsk | 0:12b53511e212 | 155 | if (!(value & 0x8000)) { |
igorsk | 0:12b53511e212 | 156 | // Reset has completed |
igorsk | 0:12b53511e212 | 157 | break; |
igorsk | 0:12b53511e212 | 158 | } |
igorsk | 0:12b53511e212 | 159 | } |
igorsk | 0:12b53511e212 | 160 | |
igorsk | 0:12b53511e212 | 161 | // Just check this actually is a DP83848C PHY |
igorsk | 0:12b53511e212 | 162 | phyid1 = ReadFromPHY (PHY_REG_IDR1); |
igorsk | 0:12b53511e212 | 163 | phyid2 = ReadFromPHY (PHY_REG_IDR2); |
igorsk | 0:12b53511e212 | 164 | |
igorsk | 0:12b53511e212 | 165 | if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == DP83848C_ID) { |
igorsk | 0:12b53511e212 | 166 | phy_in_use = DP83848C_ID; |
igorsk | 0:12b53511e212 | 167 | } |
igorsk | 0:12b53511e212 | 168 | else if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == LAN8720_ID) { |
igorsk | 0:12b53511e212 | 169 | phy_in_use = LAN8720_ID; |
igorsk | 0:12b53511e212 | 170 | } |
igorsk | 0:12b53511e212 | 171 | |
igorsk | 0:12b53511e212 | 172 | if (phy_in_use != 0) { |
igorsk | 0:12b53511e212 | 173 | // Safe to configure the PHY device |
igorsk | 0:12b53511e212 | 174 | |
igorsk | 0:12b53511e212 | 175 | // Set PHY to autonegotiation link speed |
igorsk | 0:12b53511e212 | 176 | WriteToPHY (PHY_REG_BMCR, PHY_AUTO_NEG); |
igorsk | 0:12b53511e212 | 177 | // loop until autonegotiation completes |
igorsk | 0:12b53511e212 | 178 | for (loop = 0; loop < 0x100000; loop++) { |
igorsk | 0:12b53511e212 | 179 | value = ReadFromPHY (PHY_REG_BMSR); |
igorsk | 0:12b53511e212 | 180 | if (value & 0x0020) { |
igorsk | 0:12b53511e212 | 181 | // Autonegotiation has completed |
igorsk | 0:12b53511e212 | 182 | break; |
igorsk | 0:12b53511e212 | 183 | } |
igorsk | 0:12b53511e212 | 184 | } |
igorsk | 0:12b53511e212 | 185 | } |
igorsk | 0:12b53511e212 | 186 | |
igorsk | 0:12b53511e212 | 187 | phy_linkstatus_reg = PHY_REG_STS; // Default to DP83848C |
igorsk | 0:12b53511e212 | 188 | phy_linkstatus_mask = 0x0001; |
igorsk | 0:12b53511e212 | 189 | |
igorsk | 0:12b53511e212 | 190 | if (phy_in_use == LAN8720_ID) { |
igorsk | 0:12b53511e212 | 191 | phy_linkstatus_reg = PHY_REG_BMSR; |
igorsk | 0:12b53511e212 | 192 | phy_linkstatus_mask = 0x0002; |
igorsk | 0:12b53511e212 | 193 | } |
igorsk | 0:12b53511e212 | 194 | |
igorsk | 0:12b53511e212 | 195 | // Now check the link status |
igorsk | 0:12b53511e212 | 196 | for (loop = 0; loop < 0x10000; loop++) { |
igorsk | 0:12b53511e212 | 197 | value = ReadFromPHY (phy_linkstatus_reg); |
igorsk | 0:12b53511e212 | 198 | if (value & phy_linkstatus_mask) { |
igorsk | 0:12b53511e212 | 199 | // The link is on |
igorsk | 0:12b53511e212 | 200 | break; |
igorsk | 0:12b53511e212 | 201 | } |
igorsk | 0:12b53511e212 | 202 | } |
igorsk | 0:12b53511e212 | 203 | |
igorsk | 0:12b53511e212 | 204 | // Now configure for full/half duplex mode |
igorsk | 0:12b53511e212 | 205 | if (value & 0x0004) { |
igorsk | 0:12b53511e212 | 206 | // We are in full duplex is enabled mode |
igorsk | 0:12b53511e212 | 207 | LPC_EMAC->MAC2 |= MAC2_FULL_DUP; |
igorsk | 0:12b53511e212 | 208 | LPC_EMAC->Command |= CR_FULL_DUP; |
igorsk | 0:12b53511e212 | 209 | LPC_EMAC->IPGT = IPGT_FULL_DUP; |
igorsk | 0:12b53511e212 | 210 | } |
igorsk | 0:12b53511e212 | 211 | else { |
igorsk | 0:12b53511e212 | 212 | // Otherwise we are in half duplex mode |
igorsk | 0:12b53511e212 | 213 | LPC_EMAC->IPGT = IPGT_HALF_DUP; |
igorsk | 0:12b53511e212 | 214 | } |
igorsk | 0:12b53511e212 | 215 | |
igorsk | 0:12b53511e212 | 216 | // Now configure 100MBit or 10MBit mode |
igorsk | 0:12b53511e212 | 217 | if (value & 0x0002) { |
igorsk | 0:12b53511e212 | 218 | // 10MBit mode |
igorsk | 0:12b53511e212 | 219 | LPC_EMAC->SUPP = 0; |
igorsk | 0:12b53511e212 | 220 | } |
igorsk | 0:12b53511e212 | 221 | else { |
igorsk | 0:12b53511e212 | 222 | // 100MBit mode |
igorsk | 0:12b53511e212 | 223 | LPC_EMAC->SUPP = SUPP_SPEED; |
igorsk | 0:12b53511e212 | 224 | } |
igorsk | 0:12b53511e212 | 225 | |
igorsk | 0:12b53511e212 | 226 | // Now set the Ethernet MAC Address registers |
igorsk | 0:12b53511e212 | 227 | // NOTE - MAC address must be unique on the network! |
igorsk | 0:12b53511e212 | 228 | LPC_EMAC->SA0 = (MYMAC_1 << 8) | MYMAC_2; // Station address 0 Reg |
igorsk | 0:12b53511e212 | 229 | LPC_EMAC->SA1 = (MYMAC_3 << 8) | MYMAC_4; // Station address 1 Reg |
igorsk | 0:12b53511e212 | 230 | LPC_EMAC->SA2 = (MYMAC_5 << 8) | MYMAC_6; // Station address 2 Reg |
igorsk | 0:12b53511e212 | 231 | |
igorsk | 0:12b53511e212 | 232 | |
igorsk | 0:12b53511e212 | 233 | // Now initialise the Rx descriptors |
igorsk | 0:12b53511e212 | 234 | for (loop = 0; loop < NUM_RX_FRAG; loop++) { |
igorsk | 0:12b53511e212 | 235 | RX_DESC_PACKET(loop) = RX_BUF(loop); |
igorsk | 0:12b53511e212 | 236 | RX_DESC_CTRL(loop) = RCTRL_INT | (ETH_FRAG_SIZE-1); |
igorsk | 0:12b53511e212 | 237 | RX_STAT_INFO(loop) = 0; |
igorsk | 0:12b53511e212 | 238 | RX_STAT_HASHCRC(loop) = 0; |
igorsk | 0:12b53511e212 | 239 | } |
igorsk | 0:12b53511e212 | 240 | |
igorsk | 0:12b53511e212 | 241 | // Set up the Receive Descriptor Base address register |
igorsk | 0:12b53511e212 | 242 | LPC_EMAC->RxDescriptor = RX_DESC_BASE; |
igorsk | 0:12b53511e212 | 243 | // Set up the Receive Status Base address register |
igorsk | 0:12b53511e212 | 244 | LPC_EMAC->RxStatus = RX_STAT_BASE; |
igorsk | 0:12b53511e212 | 245 | // Setup the Receive Number of Descriptor register |
igorsk | 0:12b53511e212 | 246 | LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; |
igorsk | 0:12b53511e212 | 247 | // Set Receive Consume Index register to 0 |
igorsk | 0:12b53511e212 | 248 | LPC_EMAC->RxConsumeIndex = 0; |
igorsk | 0:12b53511e212 | 249 | |
igorsk | 0:12b53511e212 | 250 | // Now initialise the Tx descriptors |
igorsk | 0:12b53511e212 | 251 | for (loop = 0; loop < NUM_TX_FRAG; loop++) { |
igorsk | 0:12b53511e212 | 252 | TX_DESC_PACKET(loop) = TX_BUF(loop); |
igorsk | 0:12b53511e212 | 253 | TX_DESC_CTRL(loop) = 0; |
igorsk | 0:12b53511e212 | 254 | TX_STAT_INFO(loop) = 0; |
igorsk | 0:12b53511e212 | 255 | } |
igorsk | 0:12b53511e212 | 256 | |
igorsk | 0:12b53511e212 | 257 | // Set up the Transmit Descriptor Base address register |
igorsk | 0:12b53511e212 | 258 | LPC_EMAC->TxDescriptor = TX_DESC_BASE; |
igorsk | 0:12b53511e212 | 259 | // Set up the Transmit Status Base address register |
igorsk | 0:12b53511e212 | 260 | LPC_EMAC->TxStatus = TX_STAT_BASE; |
igorsk | 0:12b53511e212 | 261 | // Setup the Transmit Number of Descriptor register |
igorsk | 0:12b53511e212 | 262 | LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; |
igorsk | 0:12b53511e212 | 263 | // Set Transmit Consume Index register to 0 |
igorsk | 0:12b53511e212 | 264 | LPC_EMAC->TxProduceIndex = 0; |
igorsk | 0:12b53511e212 | 265 | |
igorsk | 0:12b53511e212 | 266 | // Receive Broadcast and Perfect Match Packets |
igorsk | 0:12b53511e212 | 267 | |
igorsk | 0:12b53511e212 | 268 | |
igorsk | 0:12b53511e212 | 269 | |
igorsk | 0:12b53511e212 | 270 | LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN; |
igorsk | 0:12b53511e212 | 271 | |
igorsk | 0:12b53511e212 | 272 | // Enable interrupts MAC Module Control Interrupt Enable Register |
igorsk | 0:12b53511e212 | 273 | LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; |
igorsk | 0:12b53511e212 | 274 | |
igorsk | 0:12b53511e212 | 275 | // Reset all ethernet interrupts in MAC module |
igorsk | 0:12b53511e212 | 276 | LPC_EMAC->IntClear = 0xFFFF; |
igorsk | 0:12b53511e212 | 277 | |
igorsk | 0:12b53511e212 | 278 | // Finally enable receive and transmit mode in ethernet core |
igorsk | 0:12b53511e212 | 279 | LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); |
igorsk | 0:12b53511e212 | 280 | LPC_EMAC->MAC1 |= MAC1_REC_EN; |
igorsk | 0:12b53511e212 | 281 | } |
igorsk | 0:12b53511e212 | 282 | |
igorsk | 0:12b53511e212 | 283 | |
igorsk | 0:12b53511e212 | 284 | // CodeRed - Write8900() not needed |
igorsk | 0:12b53511e212 | 285 | // for RDB1768 port |
igorsk | 0:12b53511e212 | 286 | |
igorsk | 0:12b53511e212 | 287 | /* |
igorsk | 0:12b53511e212 | 288 | // writes a word in little-endian byte order to |
igorsk | 0:12b53511e212 | 289 | // a specified port-address |
igorsk | 0:12b53511e212 | 290 | |
igorsk | 0:12b53511e212 | 291 | void Write8900(unsigned char Address, unsigned int Data) |
igorsk | 0:12b53511e212 | 292 | { |
igorsk | 0:12b53511e212 | 293 | P5DIR = 0xFF; // data port to output |
igorsk | 0:12b53511e212 | 294 | P3OUT = IOR | IOW | Address; // put address on bus |
igorsk | 0:12b53511e212 | 295 | |
igorsk | 0:12b53511e212 | 296 | P5OUT = Data; // write low order byte to data bus |
igorsk | 0:12b53511e212 | 297 | P3OUT &= ~IOW; // toggle IOW-signal |
igorsk | 0:12b53511e212 | 298 | P3OUT = IOR | IOW | (Address + 1); // and put next address on bus |
igorsk | 0:12b53511e212 | 299 | |
igorsk | 0:12b53511e212 | 300 | P5OUT = Data >> 8; // write high order byte to data bus |
igorsk | 0:12b53511e212 | 301 | P3OUT &= ~IOW; // toggle IOW-signal |
igorsk | 0:12b53511e212 | 302 | P3OUT |= IOW; |
igorsk | 0:12b53511e212 | 303 | } |
igorsk | 0:12b53511e212 | 304 | */ |
igorsk | 0:12b53511e212 | 305 | |
igorsk | 0:12b53511e212 | 306 | // Code Red - updated for LPC1776 port |
igorsk | 0:12b53511e212 | 307 | /* |
igorsk | 0:12b53511e212 | 308 | // writes a word in little-endian byte order to TX_FRAME_PORT |
igorsk | 0:12b53511e212 | 309 | |
igorsk | 0:12b53511e212 | 310 | void WriteFrame8900(unsigned int Data) |
igorsk | 0:12b53511e212 | 311 | { |
igorsk | 0:12b53511e212 | 312 | P5DIR = 0xFF; // data port to output |
igorsk | 0:12b53511e212 | 313 | P3OUT = IOR | IOW | TX_FRAME_PORT; // put address on bus |
igorsk | 0:12b53511e212 | 314 | |
igorsk | 0:12b53511e212 | 315 | P5OUT = Data; // write low order byte to data bus |
igorsk | 0:12b53511e212 | 316 | P3OUT &= ~IOW; // toggle IOW-signal |
igorsk | 0:12b53511e212 | 317 | P3OUT = IOR | IOW | (TX_FRAME_PORT + 1); // and put next address on bus |
igorsk | 0:12b53511e212 | 318 | |
igorsk | 0:12b53511e212 | 319 | P5OUT = Data >> 8; // write high order byte to data bus |
igorsk | 0:12b53511e212 | 320 | P3OUT &= ~IOW; // toggle IOW-signal |
igorsk | 0:12b53511e212 | 321 | P3OUT |= IOW; |
igorsk | 0:12b53511e212 | 322 | } |
igorsk | 0:12b53511e212 | 323 | */ |
igorsk | 0:12b53511e212 | 324 | |
igorsk | 0:12b53511e212 | 325 | // writes a word in little-endian byte order to TX_BUFFER |
igorsk | 0:12b53511e212 | 326 | void WriteFrame_EthMAC(unsigned short Data) |
igorsk | 0:12b53511e212 | 327 | { |
igorsk | 0:12b53511e212 | 328 | *txptr++ = Data; |
igorsk | 0:12b53511e212 | 329 | } |
igorsk | 0:12b53511e212 | 330 | |
igorsk | 0:12b53511e212 | 331 | |
igorsk | 0:12b53511e212 | 332 | |
igorsk | 0:12b53511e212 | 333 | // copies bytes from MCU-memory to frame port |
igorsk | 0:12b53511e212 | 334 | // NOTES: * an odd number of byte may only be transfered |
igorsk | 0:12b53511e212 | 335 | // if the frame is written to the end! |
igorsk | 0:12b53511e212 | 336 | // * MCU-memory MUST start at word-boundary |
igorsk | 0:12b53511e212 | 337 | |
igorsk | 0:12b53511e212 | 338 | // Code Red - rewritten for LPC1776 |
igorsk | 0:12b53511e212 | 339 | /* |
igorsk | 0:12b53511e212 | 340 | void CopyToFrame8900(void *Source, unsigned int Size) |
igorsk | 0:12b53511e212 | 341 | { |
igorsk | 0:12b53511e212 | 342 | P5DIR = 0xFF; // data port to output |
igorsk | 0:12b53511e212 | 343 | |
igorsk | 0:12b53511e212 | 344 | while (Size > 1) { |
igorsk | 0:12b53511e212 | 345 | WriteFrame8900(*((unsigned int *)Source)++); |
igorsk | 0:12b53511e212 | 346 | Size -= 2; |
igorsk | 0:12b53511e212 | 347 | } |
igorsk | 0:12b53511e212 | 348 | |
igorsk | 0:12b53511e212 | 349 | if (Size) // if odd num. of bytes... |
igorsk | 0:12b53511e212 | 350 | WriteFrame8900(*(unsigned char *)Source); // write leftover byte (the LAN-controller |
igorsk | 0:12b53511e212 | 351 | } // ignores the highbyte) |
igorsk | 0:12b53511e212 | 352 | */ |
igorsk | 0:12b53511e212 | 353 | |
igorsk | 0:12b53511e212 | 354 | void CopyToFrame_EthMAC(void *Source, unsigned int Size) |
igorsk | 0:12b53511e212 | 355 | { |
igorsk | 0:12b53511e212 | 356 | unsigned int index; |
igorsk | 0:12b53511e212 | 357 | unsigned short *pSource; |
igorsk | 0:12b53511e212 | 358 | |
igorsk | 0:12b53511e212 | 359 | pSource = (unsigned short *)Source; |
igorsk | 0:12b53511e212 | 360 | Size = (Size + 1) & 0xFFFE; // round up Size to next even number |
igorsk | 0:12b53511e212 | 361 | while (Size > 0) { |
igorsk | 0:12b53511e212 | 362 | WriteFrame_EthMAC(*pSource++); |
igorsk | 0:12b53511e212 | 363 | Size -= 2; |
igorsk | 0:12b53511e212 | 364 | } |
igorsk | 0:12b53511e212 | 365 | |
igorsk | 0:12b53511e212 | 366 | index = LPC_EMAC->TxProduceIndex; |
igorsk | 0:12b53511e212 | 367 | if (++index == NUM_TX_FRAG) |
igorsk | 0:12b53511e212 | 368 | index = 0; |
igorsk | 0:12b53511e212 | 369 | LPC_EMAC->TxProduceIndex = index; |
igorsk | 0:12b53511e212 | 370 | } |
igorsk | 0:12b53511e212 | 371 | |
igorsk | 0:12b53511e212 | 372 | // CodeRed - Read8900() not needed |
igorsk | 0:12b53511e212 | 373 | // for LPC1768 port |
igorsk | 0:12b53511e212 | 374 | /* |
igorsk | 0:12b53511e212 | 375 | |
igorsk | 0:12b53511e212 | 376 | // reads a word in little-endian byte order from |
igorsk | 0:12b53511e212 | 377 | // a specified port-address |
igorsk | 0:12b53511e212 | 378 | |
igorsk | 0:12b53511e212 | 379 | unsigned int Read8900(unsigned char Address) |
igorsk | 0:12b53511e212 | 380 | { |
igorsk | 0:12b53511e212 | 381 | unsigned int ReturnValue; |
igorsk | 0:12b53511e212 | 382 | |
igorsk | 0:12b53511e212 | 383 | P5DIR = 0x00; // data port to input |
igorsk | 0:12b53511e212 | 384 | P3OUT = IOR | IOW | Address; // put address on bus |
igorsk | 0:12b53511e212 | 385 | |
igorsk | 0:12b53511e212 | 386 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 387 | |
igorsk | 0:12b53511e212 | 388 | ReturnValue = P5IN; // get low order byte from data bus |
igorsk | 0:12b53511e212 | 389 | P3OUT = IOR | IOW | (Address + 1); // IOR high and put next address on bus |
igorsk | 0:12b53511e212 | 390 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 391 | |
igorsk | 0:12b53511e212 | 392 | ReturnValue |= P5IN << 8; // get high order byte from data bus |
igorsk | 0:12b53511e212 | 393 | |
igorsk | 0:12b53511e212 | 394 | P3OUT |= IOR; |
igorsk | 0:12b53511e212 | 395 | |
igorsk | 0:12b53511e212 | 396 | return ReturnValue; |
igorsk | 0:12b53511e212 | 397 | } |
igorsk | 0:12b53511e212 | 398 | */ |
igorsk | 0:12b53511e212 | 399 | // reads a word in little-endian byte order from RX_FRAME_PORT |
igorsk | 0:12b53511e212 | 400 | |
igorsk | 0:12b53511e212 | 401 | // Code Red - ReadFrame8900 rewritten for RDB1768 port |
igorsk | 0:12b53511e212 | 402 | /* |
igorsk | 0:12b53511e212 | 403 | unsigned int ReadFrame8900(void) |
igorsk | 0:12b53511e212 | 404 | { |
igorsk | 0:12b53511e212 | 405 | unsigned int ReturnValue; |
igorsk | 0:12b53511e212 | 406 | |
igorsk | 0:12b53511e212 | 407 | P5DIR = 0x00; // data port to input |
igorsk | 0:12b53511e212 | 408 | P3OUT = IOR | IOW | RX_FRAME_PORT; // access to RX_FRAME_PORT |
igorsk | 0:12b53511e212 | 409 | |
igorsk | 0:12b53511e212 | 410 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 411 | |
igorsk | 0:12b53511e212 | 412 | ReturnValue = P5IN; // get 1st byte from data bus (low-byte) |
igorsk | 0:12b53511e212 | 413 | P3OUT = IOR | IOW | (RX_FRAME_PORT + 1); // IOR high and put next address on bus |
igorsk | 0:12b53511e212 | 414 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 415 | |
igorsk | 0:12b53511e212 | 416 | ReturnValue |= P5IN << 8; // get 2nd byte from data bus (high-byte) |
igorsk | 0:12b53511e212 | 417 | |
igorsk | 0:12b53511e212 | 418 | P3OUT |= IOR; |
igorsk | 0:12b53511e212 | 419 | |
igorsk | 0:12b53511e212 | 420 | return ReturnValue; |
igorsk | 0:12b53511e212 | 421 | } |
igorsk | 0:12b53511e212 | 422 | */ |
igorsk | 0:12b53511e212 | 423 | |
igorsk | 0:12b53511e212 | 424 | // reads a word in little-endian byte order from RX_BUFFER |
igorsk | 0:12b53511e212 | 425 | |
igorsk | 0:12b53511e212 | 426 | unsigned short ReadFrame_EthMAC(void) |
igorsk | 0:12b53511e212 | 427 | { |
igorsk | 0:12b53511e212 | 428 | return (*rxptr++); |
igorsk | 0:12b53511e212 | 429 | } |
igorsk | 0:12b53511e212 | 430 | |
igorsk | 0:12b53511e212 | 431 | |
igorsk | 0:12b53511e212 | 432 | // reads a word in big-endian byte order from RX_FRAME_PORT |
igorsk | 0:12b53511e212 | 433 | // (useful to avoid permanent byte-swapping while reading |
igorsk | 0:12b53511e212 | 434 | // TCP/IP-data) |
igorsk | 0:12b53511e212 | 435 | |
igorsk | 0:12b53511e212 | 436 | // CodeRed - rewritten for LPC1768 |
igorsk | 0:12b53511e212 | 437 | /* |
igorsk | 0:12b53511e212 | 438 | |
igorsk | 0:12b53511e212 | 439 | unsigned int ReadFrameBE8900(void) |
igorsk | 0:12b53511e212 | 440 | { |
igorsk | 0:12b53511e212 | 441 | unsigned int ReturnValue; |
igorsk | 0:12b53511e212 | 442 | |
igorsk | 0:12b53511e212 | 443 | P5DIR = 0x00; // data port to input |
igorsk | 0:12b53511e212 | 444 | P3OUT = IOR | IOW | RX_FRAME_PORT; // access to RX_FRAME_PORT |
igorsk | 0:12b53511e212 | 445 | |
igorsk | 0:12b53511e212 | 446 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 447 | |
igorsk | 0:12b53511e212 | 448 | ReturnValue = P5IN << 8; // get 1st byte from data bus (high-byte) |
igorsk | 0:12b53511e212 | 449 | P3OUT = IOR | IOW | (RX_FRAME_PORT + 1); // IOR high and put next address on bus |
igorsk | 0:12b53511e212 | 450 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 451 | |
igorsk | 0:12b53511e212 | 452 | ReturnValue |= P5IN; // get 2nd byte from data bus (low-byte) |
igorsk | 0:12b53511e212 | 453 | |
igorsk | 0:12b53511e212 | 454 | P3OUT |= IOR; |
igorsk | 0:12b53511e212 | 455 | |
igorsk | 0:12b53511e212 | 456 | return ReturnValue; |
igorsk | 0:12b53511e212 | 457 | } |
igorsk | 0:12b53511e212 | 458 | */ |
igorsk | 0:12b53511e212 | 459 | |
igorsk | 0:12b53511e212 | 460 | unsigned short ReadFrameBE_EthMAC(void) |
igorsk | 0:12b53511e212 | 461 | { |
igorsk | 0:12b53511e212 | 462 | unsigned short ReturnValue; |
igorsk | 0:12b53511e212 | 463 | |
igorsk | 0:12b53511e212 | 464 | ReturnValue = SwapBytes (*rxptr++); |
igorsk | 0:12b53511e212 | 465 | return (ReturnValue); |
igorsk | 0:12b53511e212 | 466 | } |
igorsk | 0:12b53511e212 | 467 | |
igorsk | 0:12b53511e212 | 468 | // CodeRed - not required for RDB1768 port |
igorsk | 0:12b53511e212 | 469 | /* |
igorsk | 0:12b53511e212 | 470 | // reads a word in little-endian byte order from |
igorsk | 0:12b53511e212 | 471 | // a specified port-address |
igorsk | 0:12b53511e212 | 472 | // NOTE: this func. xfers the high-byte 1st, must be used to |
igorsk | 0:12b53511e212 | 473 | // access some special registers (e.g. RxStatus) |
igorsk | 0:12b53511e212 | 474 | |
igorsk | 0:12b53511e212 | 475 | unsigned int ReadHB1ST8900(unsigned char Address) |
igorsk | 0:12b53511e212 | 476 | { |
igorsk | 0:12b53511e212 | 477 | unsigned int ReturnValue; |
igorsk | 0:12b53511e212 | 478 | |
igorsk | 0:12b53511e212 | 479 | P5DIR = 0x00; // data port to input |
igorsk | 0:12b53511e212 | 480 | P3OUT = IOR | IOW | (Address + 1); // put address on bus |
igorsk | 0:12b53511e212 | 481 | |
igorsk | 0:12b53511e212 | 482 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 483 | |
igorsk | 0:12b53511e212 | 484 | ReturnValue = P5IN << 8; // get high order byte from data bus |
igorsk | 0:12b53511e212 | 485 | P3OUT = IOR | IOW | Address; // IOR high and put next address on bus |
igorsk | 0:12b53511e212 | 486 | P3OUT &= ~IOR; // IOR-signal low |
igorsk | 0:12b53511e212 | 487 | |
igorsk | 0:12b53511e212 | 488 | ReturnValue |= P5IN; // get low order byte from data bus |
igorsk | 0:12b53511e212 | 489 | |
igorsk | 0:12b53511e212 | 490 | P3OUT |= IOR; |
igorsk | 0:12b53511e212 | 491 | |
igorsk | 0:12b53511e212 | 492 | return ReturnValue; |
igorsk | 0:12b53511e212 | 493 | } |
igorsk | 0:12b53511e212 | 494 | */ |
igorsk | 0:12b53511e212 | 495 | |
igorsk | 0:12b53511e212 | 496 | |
igorsk | 0:12b53511e212 | 497 | // copies bytes from frame port to MCU-memory |
igorsk | 0:12b53511e212 | 498 | // NOTES: * an odd number of byte may only be transfered |
igorsk | 0:12b53511e212 | 499 | // if the frame is read to the end! |
igorsk | 0:12b53511e212 | 500 | // * MCU-memory MUST start at word-boundary |
igorsk | 0:12b53511e212 | 501 | |
igorsk | 0:12b53511e212 | 502 | // Code Red - rewritten for LPC1776 port |
igorsk | 0:12b53511e212 | 503 | /* |
igorsk | 0:12b53511e212 | 504 | void CopyFromFrame8900(void *Dest, unsigned int Size) |
igorsk | 0:12b53511e212 | 505 | { |
igorsk | 0:12b53511e212 | 506 | while (Size > 1) { |
igorsk | 0:12b53511e212 | 507 | *((unsigned int *)Dest)++ = ReadFrame8900(); |
igorsk | 0:12b53511e212 | 508 | Size -= 2; |
igorsk | 0:12b53511e212 | 509 | } |
igorsk | 0:12b53511e212 | 510 | |
igorsk | 0:12b53511e212 | 511 | if (Size) // check for leftover byte... |
igorsk | 0:12b53511e212 | 512 | *(unsigned char *)Dest = ReadFrame8900(); // the LAN-Controller will return 0 |
igorsk | 0:12b53511e212 | 513 | } // for the highbyte |
igorsk | 0:12b53511e212 | 514 | */ |
igorsk | 0:12b53511e212 | 515 | |
igorsk | 0:12b53511e212 | 516 | void CopyFromFrame_EthMAC(void *Dest, unsigned short Size) |
igorsk | 0:12b53511e212 | 517 | { |
igorsk | 0:12b53511e212 | 518 | unsigned short *pDest; |
igorsk | 0:12b53511e212 | 519 | |
igorsk | 0:12b53511e212 | 520 | pDest = (unsigned short *)Dest; |
igorsk | 0:12b53511e212 | 521 | while (Size > 1) { |
igorsk | 0:12b53511e212 | 522 | *pDest++ = ReadFrame_EthMAC(); |
igorsk | 0:12b53511e212 | 523 | Size -= 2; |
igorsk | 0:12b53511e212 | 524 | } |
igorsk | 0:12b53511e212 | 525 | |
igorsk | 0:12b53511e212 | 526 | if (Size) { // check for leftover byte... |
igorsk | 0:12b53511e212 | 527 | *(unsigned char *)pDest = (char)ReadFrame_EthMAC();// the LAN-Controller will return 0 |
igorsk | 0:12b53511e212 | 528 | } // for the highbyte |
igorsk | 0:12b53511e212 | 529 | } |
igorsk | 0:12b53511e212 | 530 | |
igorsk | 0:12b53511e212 | 531 | |
igorsk | 0:12b53511e212 | 532 | |
igorsk | 0:12b53511e212 | 533 | // does a dummy read on frame-I/O-port |
igorsk | 0:12b53511e212 | 534 | // NOTE: only an even number of bytes is read! |
igorsk | 0:12b53511e212 | 535 | |
igorsk | 0:12b53511e212 | 536 | // Code Red - updated for LPC1776 |
igorsk | 0:12b53511e212 | 537 | //void DummyReadFrame8900(unsigned int Size) // discards an EVEN number of bytes |
igorsk | 0:12b53511e212 | 538 | void DummyReadFrame_EthMAC(unsigned short Size) // discards an EVEN number of bytes |
igorsk | 0:12b53511e212 | 539 | { // from RX-fifo |
igorsk | 0:12b53511e212 | 540 | while (Size > 1) { |
igorsk | 0:12b53511e212 | 541 | // Code Red - updated for LPC1776 |
igorsk | 0:12b53511e212 | 542 | // ReadFrame8900(); |
igorsk | 0:12b53511e212 | 543 | ReadFrame_EthMAC(); |
igorsk | 0:12b53511e212 | 544 | Size -= 2; |
igorsk | 0:12b53511e212 | 545 | } |
igorsk | 0:12b53511e212 | 546 | } |
igorsk | 0:12b53511e212 | 547 | |
igorsk | 0:12b53511e212 | 548 | // requests space in CS8900's on-chip memory for |
igorsk | 0:12b53511e212 | 549 | // storing an outgoing frame |
igorsk | 0:12b53511e212 | 550 | |
igorsk | 0:12b53511e212 | 551 | // CodeRed - updated for LPC1768 port |
igorsk | 0:12b53511e212 | 552 | /* |
igorsk | 0:12b53511e212 | 553 | void RequestSend(unsigned int FrameSize) |
igorsk | 0:12b53511e212 | 554 | { |
igorsk | 0:12b53511e212 | 555 | Write8900(TX_CMD_PORT, TX_START_ALL_BYTES); |
igorsk | 0:12b53511e212 | 556 | Write8900(TX_LEN_PORT, FrameSize); |
igorsk | 0:12b53511e212 | 557 | } |
igorsk | 0:12b53511e212 | 558 | */ |
igorsk | 0:12b53511e212 | 559 | void RequestSend(unsigned short FrameSize) |
igorsk | 0:12b53511e212 | 560 | { |
igorsk | 0:12b53511e212 | 561 | unsigned int index; |
igorsk | 0:12b53511e212 | 562 | index = LPC_EMAC->TxProduceIndex; |
igorsk | 0:12b53511e212 | 563 | txptr = (unsigned short *)TX_DESC_PACKET(index); |
igorsk | 0:12b53511e212 | 564 | TX_DESC_CTRL(index) = FrameSize | TCTRL_LAST; |
igorsk | 0:12b53511e212 | 565 | } |
igorsk | 0:12b53511e212 | 566 | |
igorsk | 0:12b53511e212 | 567 | // check if CS8900 is ready to accept the |
igorsk | 0:12b53511e212 | 568 | // frame we want to send |
igorsk | 0:12b53511e212 | 569 | |
igorsk | 0:12b53511e212 | 570 | unsigned int Rdy4Tx(void) |
igorsk | 0:12b53511e212 | 571 | { |
igorsk | 0:12b53511e212 | 572 | // Code Red - updated for LPC1768 |
igorsk | 0:12b53511e212 | 573 | // Write8900(ADD_PORT, PP_BusST); |
igorsk | 0:12b53511e212 | 574 | // return (Read8900(DATA_PORT) & READY_FOR_TX_NOW); |
igorsk | 0:12b53511e212 | 575 | |
igorsk | 0:12b53511e212 | 576 | // One the LPC the ethernet controller transmits |
igorsk | 0:12b53511e212 | 577 | // much faster than the CPU can load its buffers |
igorsk | 0:12b53511e212 | 578 | // so will always be ready to accept frame |
igorsk | 0:12b53511e212 | 579 | return (1); |
igorsk | 0:12b53511e212 | 580 | // |
igorsk | 0:12b53511e212 | 581 | } |
igorsk | 0:12b53511e212 | 582 | |
igorsk | 0:12b53511e212 | 583 | // CodeRed - New function |
igorsk | 0:12b53511e212 | 584 | |
igorsk | 0:12b53511e212 | 585 | // Reads length of received ethernet frame and checks |
igorsk | 0:12b53511e212 | 586 | // if destination address is a broadcast message or not. |
igorsk | 0:12b53511e212 | 587 | // Then returns the frame length |
igorsk | 0:12b53511e212 | 588 | unsigned short StartReadingFrame(void) |
igorsk | 0:12b53511e212 | 589 | { |
igorsk | 0:12b53511e212 | 590 | unsigned short ReceiveLength; |
igorsk | 0:12b53511e212 | 591 | unsigned int index; |
igorsk | 0:12b53511e212 | 592 | |
igorsk | 0:12b53511e212 | 593 | index = LPC_EMAC->RxConsumeIndex; |
igorsk | 0:12b53511e212 | 594 | ReceiveLength = (RX_STAT_INFO(index) & RINFO_SIZE) - 3; |
igorsk | 0:12b53511e212 | 595 | rxptr = (unsigned short *)RX_DESC_PACKET(index); |
igorsk | 0:12b53511e212 | 596 | return(ReceiveLength); |
igorsk | 0:12b53511e212 | 597 | } |
igorsk | 0:12b53511e212 | 598 | |
igorsk | 0:12b53511e212 | 599 | // CodeRed - new function |
igorsk | 0:12b53511e212 | 600 | |
igorsk | 0:12b53511e212 | 601 | void StopReadingFrame(void) |
igorsk | 0:12b53511e212 | 602 | { |
igorsk | 0:12b53511e212 | 603 | unsigned int index; |
igorsk | 0:12b53511e212 | 604 | index = LPC_EMAC->RxConsumeIndex; |
igorsk | 0:12b53511e212 | 605 | if (++index == NUM_RX_FRAG) index = 0; |
igorsk | 0:12b53511e212 | 606 | LPC_EMAC->RxConsumeIndex = index; |
igorsk | 0:12b53511e212 | 607 | } |
igorsk | 0:12b53511e212 | 608 | |
igorsk | 0:12b53511e212 | 609 | // CodeRed - new function to check if frame has been received |
igorsk | 0:12b53511e212 | 610 | unsigned int CheckIfFrameReceived(void) |
igorsk | 0:12b53511e212 | 611 | { |
igorsk | 0:12b53511e212 | 612 | if (LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex) |
igorsk | 0:12b53511e212 | 613 | return(1); // Yes, packet received |
igorsk | 0:12b53511e212 | 614 | else |
igorsk | 0:12b53511e212 | 615 | return(0); |
igorsk | 0:12b53511e212 | 616 | } |