Webserver basic for CDU

Dependencies:   mbed

Fork of EasyWebCR by Igor Skochinsky

Committer:
igorsk
Date:
Fri Jan 29 21:46:31 2010 +0000
Revision:
0:12b53511e212

        

Who changed what in which revision?

UserRevisionLine numberNew 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 }