ban4jp -
/
uIP-1-0_webserver
uIP 1.0 based webserver for LPC1114 + ENC28J60
Embed:
(wiki syntax)
Show/hide line numbers
enc28j60.cpp
00001 #include "mbed.h" 00002 00003 #include "enc28j60.h" 00004 #include "uip-conf.h" 00005 00006 u8 Enc28j60Bank; 00007 u16 NextPacketPtr; 00008 00009 ENC28J60::ENC28J60(SPI* _spi, PinName _cs, PinName _int): 00010 cs_pin(_cs), int_pin(_int) 00011 { 00012 this->spi = _spi; 00013 00014 this->spi->format(8,0); 00015 this->spi->frequency(8000000); 00016 00017 cs_pin = 1; 00018 } 00019 00020 u8 ENC28J60::readOp(u8 op, u8 address) 00021 { 00022 u8 data; 00023 00024 // assert CS 00025 cs_pin = 0; 00026 00027 // issue read command 00028 spi->write(op | (address & ADDR_MASK)); 00029 // read data 00030 data = spi->write(0x00); 00031 // do dummy read if needed 00032 if(address & 0x80) 00033 { 00034 data = spi->write(0x00); 00035 } 00036 00037 // release CS 00038 cs_pin = 1; 00039 00040 return data; 00041 } 00042 00043 void ENC28J60::writeOp(u8 op, u8 address, u8 data) 00044 { 00045 // assert CS 00046 cs_pin = 0; 00047 00048 // issue write command 00049 spi->write(op | (address & ADDR_MASK)); 00050 // write data 00051 spi->write(data); 00052 00053 // release CS 00054 cs_pin = 1; 00055 } 00056 00057 void ENC28J60::readBuffer(u16 len, u8* data) 00058 { 00059 // assert CS 00060 cs_pin = 0; 00061 00062 // issue read command 00063 spi->write(ENC28J60_READ_BUF_MEM); 00064 while(len--) 00065 { 00066 // read data 00067 *data++ = spi->write(0x00); 00068 } 00069 00070 // release CS 00071 cs_pin = 1; 00072 } 00073 00074 void ENC28J60::writeBuffer(u16 len, u8* data) 00075 { 00076 // assert CS 00077 cs_pin = 0; 00078 00079 // issue write command 00080 spi->write(ENC28J60_WRITE_BUF_MEM); 00081 while(len--) 00082 { 00083 // write data 00084 spi->write(*data++); 00085 } 00086 00087 // release CS 00088 cs_pin = 1; 00089 } 00090 00091 void ENC28J60::setBank(u8 address) 00092 { 00093 // set the bank (if needed) 00094 if((address & BANK_MASK) != Enc28j60Bank) 00095 { 00096 // set the bank 00097 this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); 00098 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); 00099 Enc28j60Bank = (address & BANK_MASK); 00100 } 00101 } 00102 00103 u8 ENC28J60::read(u8 address) 00104 { 00105 // set the bank 00106 this->setBank(address); 00107 // do the read 00108 return this->readOp(ENC28J60_READ_CTRL_REG, address); 00109 } 00110 00111 void ENC28J60::write(u8 address, u8 data) 00112 { 00113 // set the bank 00114 this->setBank(address); 00115 // do the write 00116 this->writeOp(ENC28J60_WRITE_CTRL_REG, address, data); 00117 } 00118 00119 u16 ENC28J60::phyRead(u8 address) 00120 { 00121 u16 data; 00122 00123 // Set the right address and start the register read operation 00124 this->write(MIREGADR, address); 00125 this->write(MICMD, MICMD_MIIRD); 00126 00127 // wait until the PHY read completes 00128 while(this->read(MISTAT) & MISTAT_BUSY); 00129 00130 // quit reading 00131 this->write(MICMD, 0x00); 00132 00133 // get data value 00134 data = this->read(MIRDL); 00135 data |= this->read(MIRDH); 00136 // return the data 00137 return data; 00138 } 00139 00140 void ENC28J60::phyWrite(u8 address, u16 data) 00141 { 00142 // set the PHY register address 00143 this->write(MIREGADR, address); 00144 00145 // write the PHY data 00146 this->write(MIWRL, data); 00147 this->write(MIWRH, data>>8); 00148 00149 // wait until the PHY write completes 00150 while(this->read(MISTAT) & MISTAT_BUSY); 00151 } 00152 00153 void ENC28J60::init(void) 00154 { 00155 cs_pin = 1; //Disable CS 00156 00157 // perform system reset 00158 this->writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); 00159 // check CLKRDY bit to see if reset is complete 00160 /* Fix Errata */ 00161 wait_ms(1); 00162 while(!(this->read(ESTAT) & ESTAT_CLKRDY)); 00163 00164 // do bank 0 stuff 00165 // initialize receive buffer 00166 // 16-bit transfers, must write low byte first 00167 // set receive buffer start address 00168 NextPacketPtr = RXSTART_INIT; 00169 this->write(ERXSTL, RXSTART_INIT&0xFF); 00170 this->write(ERXSTH, RXSTART_INIT>>8); 00171 // set read pointer address 00172 //this->write(ERDPTL, 0); 00173 //this->write(ERDPTH, 0); 00174 // set receive pointer address 00175 this->write(ERXRDPTL, RXSTART_INIT&0xFF); 00176 this->write(ERXRDPTH, RXSTART_INIT>>8); 00177 // set receive buffer end 00178 // ERXND defaults to 0x1FFF (end of ram) 00179 this->write(ERXNDL, RXSTOP_INIT&0xFF); 00180 this->write(ERXNDH, RXSTOP_INIT>>8); 00181 // set transmit buffer start 00182 // ETXST defaults to 0x0000 (beginnging of ram) 00183 this->write(ETXSTL, TXSTART_INIT&0xFF); 00184 this->write(ETXSTH, TXSTART_INIT>>8); 00185 00186 // do bank 2 stuff 00187 // enable MAC receive 00188 this->write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); 00189 // bring MAC out of reset 00190 this->write(MACON2, 0x00); 00191 // enable automatic padding and CRC operations 00192 this->writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); 00193 // this->write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); 00194 // set inter-frame gap (non-back-to-back) 00195 this->write(MAIPGL, 0x12); 00196 this->write(MAIPGH, 0x0C); 00197 // set inter-frame gap (back-to-back) 00198 this->write(MABBIPG, 0x12); 00199 // Set the maximum packet size which the controller will accept 00200 this->write(MAMXFLL, MAX_FRAMELEN&0xFF); 00201 this->write(MAMXFLH, MAX_FRAMELEN>>8); 00202 00203 // do bank 3 stuff 00204 // write MAC address 00205 // NOTE: MAC address in ENC28J60 is byte-backward 00206 this->write(MAADR5, UIP_ETHADDR0); 00207 this->write(MAADR4, UIP_ETHADDR1); 00208 this->write(MAADR3, UIP_ETHADDR2); 00209 this->write(MAADR2, UIP_ETHADDR3); 00210 this->write(MAADR1, UIP_ETHADDR4); 00211 this->write(MAADR0, UIP_ETHADDR5); 00212 00213 // no loopback of transmitted frames 00214 this->phyWrite(PHCON2, PHCON2_HDLDIS); 00215 00216 // switch to bank 0 00217 this->setBank(ECON1); 00218 // enable interrutps 00219 this->writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); 00220 // enable packet reception 00221 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); 00222 /* 00223 this->phyWrite(PHLCON, 0x0AA2); 00224 00225 // setup duplex ---------------------- 00226 00227 // Disable receive logic and abort any packets currently being transmitted 00228 this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN); 00229 00230 { 00231 u16 temp; 00232 // Set the PHY to the proper duplex mode 00233 temp = enc28j60PhyRead(PHCON1); 00234 temp &= ~PHCON1_PDPXMD; 00235 this->phyWrite(PHCON1, temp); 00236 // Set the MAC to the proper duplex mode 00237 temp = this->read(MACON3); 00238 temp &= ~MACON3_FULDPX; 00239 this->write(MACON3, temp); 00240 } 00241 00242 // Set the back-to-back inter-packet gap time to IEEE specified 00243 // requirements. The meaning of the MABBIPG value changes with the duplex 00244 // state, so it must be updated in this function. 00245 // In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex 00246 //this->write(MABBIPG, DuplexState ? 0x15 : 0x12); 00247 00248 // Reenable receive logic 00249 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); 00250 00251 // setup duplex ---------------------- 00252 */ 00253 } 00254 00255 void ENC28J60::packetSend(unsigned int len, unsigned char* packet) 00256 { 00257 //Errata: Transmit Logic reset 00258 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); 00259 wait_us(10); 00260 this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); 00261 00262 // Set the write pointer to start of transmit buffer area 00263 this->write(EWRPTL, TXSTART_INIT); 00264 this->write(EWRPTH, TXSTART_INIT>>8); 00265 // Set the TXND pointer to correspond to the packet size given 00266 this->write(ETXNDL, (TXSTART_INIT+len)); 00267 this->write(ETXNDH, (TXSTART_INIT+len)>>8); 00268 00269 // write per-packet control byte 00270 this->writeOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); 00271 00272 // copy the packet into the transmit buffer 00273 this->writeBuffer(len, packet); 00274 00275 // send the contents of the transmit buffer onto the network 00276 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); 00277 00278 while(this->readOp(ENC28J60_BIT_FIELD_SET, ECON1) & ECON1_TXRTS) 00279 { 00280 wait_us(10); 00281 } 00282 } 00283 00284 void ENC28J60::packetSend2(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2) 00285 { 00286 //Errata: Transmit Logic reset 00287 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); 00288 this->writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); 00289 00290 // Set the write pointer to start of transmit buffer area 00291 this->write(EWRPTL, TXSTART_INIT); 00292 this->write(EWRPTH, TXSTART_INIT>>8); 00293 // Set the TXND pointer to correspond to the packet size given 00294 this->write(ETXNDL, (TXSTART_INIT+len1+len2)); 00295 this->write(ETXNDH, (TXSTART_INIT+len1+len2)>>8); 00296 00297 // write per-packet control byte 00298 this->writeOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); 00299 00300 // copy the packet into the transmit buffer 00301 this->writeBuffer(len1, packet1); 00302 if(len2>0) this->writeBuffer(len2, packet2); 00303 00304 // send the contents of the transmit buffer onto the network 00305 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); 00306 } 00307 00308 unsigned int ENC28J60::packetReceive(unsigned int maxlen, unsigned char* packet) 00309 { 00310 u16 rxstat; 00311 u16 len; 00312 00313 // check if a packet has been received and buffered 00314 if( !(this->read(EIR) & EIR_PKTIF) ) 00315 { 00316 if(this->read(EPKTCNT) == 0) 00317 { 00318 return 0; 00319 } 00320 } 00321 00322 // Make absolutely certain that any previous packet was discarded 00323 //if( WasDiscarded == FALSE) 00324 // MACDiscardRx(); 00325 00326 // Set the read pointer to the start of the received packet 00327 this->write(ERDPTL, (NextPacketPtr)); 00328 this->write(ERDPTH, (NextPacketPtr)>>8); 00329 // read the next packet pointer 00330 NextPacketPtr = this->readOp(ENC28J60_READ_BUF_MEM, 0); 00331 NextPacketPtr |= this->readOp(ENC28J60_READ_BUF_MEM, 0)<<8; 00332 // read the packet length 00333 len = this->readOp(ENC28J60_READ_BUF_MEM, 0); 00334 len |= this->readOp(ENC28J60_READ_BUF_MEM, 0)<<8; 00335 // read the receive status 00336 rxstat = this->readOp(ENC28J60_READ_BUF_MEM, 0); 00337 rxstat |= this->readOp(ENC28J60_READ_BUF_MEM, 0)<<8; 00338 00339 // limit retrieve length 00340 // (we reduce the MAC-reported length by 4 to remove the CRC) 00341 if(len>maxlen){ 00342 len=maxlen; 00343 } 00344 00345 // copy the packet from the receive buffer 00346 this->readBuffer(len, packet); 00347 00348 // Move the RX read pointer to the start of the next received packet 00349 // This frees the memory we just read out 00350 /* Fix Errata */ 00351 if(NextPacketPtr == RXSTART_INIT) 00352 { 00353 this->write(ERXRDPTL, (RXSTOP_INIT)); 00354 this->write(ERXRDPTH, (RXSTOP_INIT)>>8); 00355 } 00356 else 00357 { 00358 this->write(ERXRDPTL, (NextPacketPtr)); 00359 this->write(ERXRDPTH, (NextPacketPtr)>>8); 00360 } 00361 00362 // decrement the packet counter indicate we are done with this packet 00363 this->writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); 00364 wait_us(11); 00365 00366 return len; 00367 } 00368 00369 void ENC28J60::receiveOverflowRecover(void) 00370 { 00371 // receive buffer overflow handling procedure 00372 00373 // recovery completed 00374 } 00375 00376 void ENC28J60::regDump(void) 00377 { 00378 printf("RevID: 0x%x\n", this->read(EREVID)); 00379 00380 printf("Ctrl: "); 00381 printf("ECON1=%x ",this->read(ECON1)); 00382 printf("ECON2=%x ",this->read(ECON2)); 00383 printf("ESTAT=%x ",this->read(ESTAT)); 00384 printf("EIR=%x ",this->read(EIR)); 00385 printf("EIE=%x\n",this->read(EIE)); 00386 00387 printf("MAC: "); 00388 printf("MACON1=%x ",this->read(MACON1)); 00389 printf("MACON2=%x ",this->read(MACON2)); 00390 printf("MACON3=%x ",this->read(MACON3)); 00391 printf("MACON4=%x ",this->read(MACON4)); 00392 printf("MAD=%x%x\n", 00393 this->read(MAADR5)*0x1000000+this->read(MAADR4)*0x10000+this->read(MAADR3)*0x100+this->read(MAADR2), 00394 this->read(MAADR1)*0x1000000+this->read(MAADR0)*0x10000+0xffff); 00395 00396 printf("Rx: "); 00397 printf("ERXST=%04x ",this->read(ERXSTH)*0x100+this->read(ERXSTL)); 00398 printf("ERXND=%04x ",this->read(ERXNDH)*0x100+this->read(ERXNDL)); 00399 printf("ERXWRPT=%x ",this->read(ERXWRPTH)*0x100+this->read(ERXWRPTL)); 00400 printf("ERXRDPT=%x ",this->read(ERXRDPTH)*0x100+this->read(ERXRDPTL)); 00401 printf("ERXFCON=%x ",this->read(ERXFCON)); 00402 printf("EPKTCNT=%x ",this->read(EPKTCNT)); 00403 printf("MAMXFL=%x\n",this->read(MAMXFLH)*0x100+this->read(MAMXFLL)); 00404 00405 printf("Tx: "); 00406 printf("ETXST=%04x ",this->read(ETXSTH)*0x100+this->read(ETXSTL)); 00407 printf("ETXND=%04x ",this->read(ETXNDH)*0x100+this->read(ETXNDL)); 00408 printf("MACLCON1=%x ",this->read(MACLCON1)); 00409 printf("MACLCON2=%x ",this->read(MACLCON2)); 00410 printf("MAPHSUP=%x\n",this->read(MAPHSUP)); 00411 }
Generated on Tue Jul 12 2022 12:52:12 by 1.7.2