Fork for fixes
Embed:
(wiki syntax)
Show/hide line numbers
Enc28j60Eth.cpp
00001 /* 00002 Enc28J60Network.cpp 00003 UIPEthernet network driver for Microchip ENC28J60 Ethernet Interface. 00004 00005 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de> 00006 All rights reserved. 00007 00008 based on enc28j60.c file from the AVRlib library by Pascal Stang. 00009 For AVRlib See http://www.procyonengineering.com/ 00010 00011 Modified (ported to mbed) by Zoltan Hudak <hudakz@inbox.com> 00012 00013 This program is free software: you can redistribute it and/or modify 00014 it under the terms of the GNU General Public License as published by 00015 the Free Software Foundation, either version 3 of the License, or 00016 (at your option) any later version. 00017 00018 This program is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 GNU General Public License for more details. 00022 00023 You should have received a copy of the GNU General Public License 00024 along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 */ 00026 #include "Enc28j60Eth.h" 00027 #include "mbed.h" 00028 #include "mbed_version.h" 00029 00030 extern "C" 00031 { 00032 #include "enc28j60.h" 00033 #include "uip.h" 00034 } 00035 00036 // Static member initialization 00037 uint16_t Enc28j60Eth::nextPacketPtr; 00038 uint8_t Enc28j60Eth::bank = 0xff; 00039 struct memblock Enc28j60Eth::receivePkt; 00040 00041 /** 00042 * @brief 00043 * @note 00044 * @param 00045 * @retval 00046 */ 00047 Enc28j60Eth::Enc28j60Eth(PinName mosi, PinName miso, PinName sclk, PinName cs) : 00048 MemPool(), 00049 _spi(mosi, miso, sclk), 00050 _cs(cs) 00051 { } 00052 00053 /** 00054 * @brief 00055 * @note 00056 * @param 00057 * @retval 00058 */ 00059 void Enc28j60Eth::init(uint8_t* macaddr) 00060 { 00061 MemPool::init(); // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte 00062 00063 // initialize SPI interface 00064 _cs = 1; 00065 _spi.format(8, 0); // 8-bit, mode 0 00066 _spi.frequency(10000000); // 10 Mbit/s 00067 #if MBED_MAJOR_VERSION == 2 00068 wait_ms(100); 00069 #else 00070 thread_sleep_for(100); 00071 #endif 00072 00073 // perform system reset 00074 writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); 00075 00076 // check CLKRDY bit to see if reset is complete 00077 // while(!(readReg(ESTAT) & ESTAT_CLKRDY)); 00078 // The CLKRDY does not work. See Rev. B4 Silicon Errata point. 00079 // Just wait. 00080 #if MBED_MAJOR_VERSION == 2 00081 wait_ms(50); 00082 #else 00083 thread_sleep_for(50); 00084 #endif 00085 00086 // do bank 0 stuff 00087 // initialize receive buffer 00088 // 16-bit transfers, must write low byte first 00089 // set receive buffer start address 00090 nextPacketPtr = RXSTART_INIT; 00091 00092 // Rx start 00093 writeRegPair(ERXSTL, RXSTART_INIT); 00094 00095 // set receive pointer address 00096 writeRegPair(ERXRDPTL, RXSTART_INIT); 00097 00098 // RX end 00099 writeRegPair(ERXNDL, RXEND_INIT); 00100 00101 //All memory which is not used by the receive buffer is considered the transmission buffer. 00102 // No explicit action is required to initialize the transmission buffer. 00103 // TX start 00104 //writeRegPair(ETXSTL, TXSTART_INIT); 00105 // TX end 00106 //writeRegPair(ETXNDL, TXEND_INIT); 00107 // However, he host controller should leave at least seven bytes between each 00108 // packet and the beginning of the receive buffer. 00109 00110 // do bank 1 stuff, packet filter: 00111 // For broadcast packets we allow only ARP packtets 00112 // All other packets should be unicast only for our mac (MAADR) 00113 // 00114 // The pattern to match is therefore 00115 // Type ETH.DST 00116 // ARP BROADCAST 00117 // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 00118 // in binary these poitions are:11 0000 0011 1111 00119 // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 00120 //TODO define specific pattern to receive dhcp-broadcast packages instead of setting ERFCON_BCEN! 00121 writeReg(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN | ERXFCON_BCEN); 00122 writeRegPair(EPMM0, 0x303f); 00123 writeRegPair(EPMCSL, 0xf7f9); 00124 00125 // 00126 // 00127 // do bank 2 stuff, 00128 // enable MAC receive 00129 // and bring MAC out of reset (writes 0x00 to MACON2) 00130 writeRegPair(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS); 00131 00132 // enable automatic padding to 60bytes and CRC operations 00133 writeOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN); 00134 00135 // set inter-frame gap (non-back-to-back) 00136 writeRegPair(MAIPGL, 0x0C12); 00137 00138 // set inter-frame gap (back-to-back) 00139 writeReg(MABBIPG, 0x12); 00140 00141 // Set the maximum packet size which the controller will accept 00142 // Do not send packets longer than MAX_FRAMELEN: 00143 writeRegPair(MAMXFLL, MAX_FRAMELEN); 00144 00145 // do bank 3 stuff 00146 // write MAC address 00147 // NOTE: MAC address in ENC28J60 is byte-backward 00148 writeReg(MAADR5, macaddr[0]); 00149 writeReg(MAADR4, macaddr[1]); 00150 writeReg(MAADR3, macaddr[2]); 00151 writeReg(MAADR2, macaddr[3]); 00152 writeReg(MAADR1, macaddr[4]); 00153 writeReg(MAADR0, macaddr[5]); 00154 00155 // no loopback of transmitted frames 00156 phyWrite(PHCON2, PHCON2_HDLDIS); 00157 00158 // switch to bank 0 00159 setBank(ECON1); 00160 00161 // enable interrutps 00162 writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE); 00163 00164 // enable packet reception 00165 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); 00166 00167 //Configure leds 00168 phyWrite(PHLCON, 0x476); 00169 } 00170 00171 /** 00172 * @brief 00173 * @note 00174 * @param 00175 * @retval 00176 */ 00177 memhandle Enc28j60Eth::receivePacket() 00178 { 00179 uint8_t rxstat; 00180 uint16_t len; 00181 // check if a packet has been received and buffered 00182 //if( !(readReg(EIR) & EIR_PKTIF) ){ 00183 // The above does not work. See Rev. B4 Silicon Errata point 6. 00184 if (readReg(EPKTCNT) != 0) { 00185 uint16_t readPtr = (nextPacketPtr + 00186 6 > RXEND_INIT) ? (nextPacketPtr + 00187 6 - 00188 RXEND_INIT + 00189 RXSTART_INIT) : (nextPacketPtr + 00190 6); 00191 // Set the read pointer to the start of the received packet 00192 writeRegPair(ERDPTL, nextPacketPtr); 00193 00194 // read the next packet pointer 00195 nextPacketPtr = readOp(ENC28J60_READ_BUF_MEM, 0); 00196 nextPacketPtr |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; 00197 00198 // read the packet length (see datasheet page 43) 00199 len = readOp(ENC28J60_READ_BUF_MEM, 0); 00200 len |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; 00201 len -= 4; //remove the CRC count 00202 // read the receive status (see datasheet page 43) 00203 rxstat = readOp(ENC28J60_READ_BUF_MEM, 0); 00204 00205 //rxstat |= readOp(ENC28J60_READ_BUF_MEM, 0) << 8; 00206 #ifdef ENC28J60DEBUG 00207 uint16_t start = readPtr; 00208 uint16_t end = start + len -1; //todo: why -1 ? 00209 00210 printf 00211 ( 00212 "receivePacket [%d-%d] (%d) (%d), next: %d, stat: %d, count: %d -> ", 00213 readPtr, 00214 (readPtr + len), 00215 len, 00216 (readPtr + len) % (RXEND_INIT + 1), // todo: what is RXEND_INIT ? 00217 nextPacketPtr, 00218 rxstat, 00219 readReg(EPKTCNT) 00220 ); 00221 (rxstat & 0x80) != 0 ? printf("OK") : printf("failed"); 00222 00223 printf("\r\n"); 00224 00225 int j = 1; 00226 for (uint16_t i = start; i < end; i++) { 00227 printf("%02x ", readByte(i)); 00228 if (j%8==0) printf(" "); 00229 if (j%16==0) printf("\r\n"); 00230 j++; 00231 } 00232 00233 printf("\r\n"); 00234 #endif 00235 // decrement the packet counter indicate we are done with this packet 00236 00237 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); 00238 00239 // check CRC and symbol errors (see datasheet page 44, table 7-3): 00240 // The ERXFCON.CRCEN is set by default. Normally we should not 00241 // need to check this. 00242 if ((rxstat & 0x80) != 0) { 00243 receivePkt.begin = readPtr; 00244 receivePkt.size = len; 00245 return UIP_RECEIVEBUFFERHANDLE; 00246 } 00247 00248 // Move the RX read pointer to the start of the next received packet 00249 // This frees the memory we just read out 00250 setERXRDPT(); 00251 } 00252 00253 return(NOBLOCK); 00254 } 00255 00256 /** 00257 * @brief 00258 * @note 00259 * @param 00260 * @retval 00261 */ 00262 void Enc28j60Eth::setERXRDPT() 00263 { 00264 uint16_t tmp = (nextPacketPtr == RXSTART_INIT) ? RXEND_INIT : nextPacketPtr - 1; 00265 00266 #ifdef ENC28J60DEBUG 00267 printf("setERXRDPT set %d start %d end %d \r\n",tmp,RXSTART_INIT,RXEND_INIT); 00268 #endif 00269 00270 writeRegPair(ERXRDPTL, tmp); 00271 } 00272 00273 /** 00274 * @brief 00275 * @note 00276 * @param 00277 * @retval 00278 */ 00279 size_t Enc28j60Eth::blockSize(memhandle handle) 00280 { 00281 return handle == NOBLOCK ? 0 : handle == UIP_RECEIVEBUFFERHANDLE ? receivePkt.size : blocks[handle].size; 00282 } 00283 00284 /** 00285 * @brief 00286 * @note 00287 * @param 00288 * @retval 00289 */ 00290 void Enc28j60Eth::sendPacket(memhandle handle) 00291 { 00292 memblock* packet = &blocks[handle]; 00293 uint16_t start = packet->begin - 1; 00294 uint16_t end = start + packet->size; 00295 00296 // backup data at control-byte position 00297 uint8_t data = readByte(start); 00298 // write control-byte (if not 0 anyway) 00299 if (data) 00300 writeByte(start, 0); 00301 00302 #ifdef ENC28J60DEBUG 00303 printf("sendPacket(%d) [%d-%d]\r\n", handle, start, end); 00304 int j = 1; 00305 for (uint16_t i = start+1; i <= end; i++) { 00306 printf("%02x ", readByte(i)); 00307 if (j%8==0) printf(" "); 00308 if (j%16==0) printf("\r\n"); 00309 j++; 00310 } 00311 00312 printf("\r\n"); 00313 #endif 00314 // TX start 00315 00316 writeRegPair(ETXSTL, start); 00317 00318 // Set the TXND pointer to correspond to the packet size given 00319 writeRegPair(ETXNDL, end); 00320 00321 // send the contents of the transmit buffer onto the network 00322 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); 00323 00324 // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. 00325 if ((readReg(EIR) & EIR_TXERIF)) { 00326 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); 00327 } 00328 00329 //restore data on control-byte position 00330 if (data) 00331 writeByte(start, data); 00332 } 00333 00334 /** 00335 * @brief 00336 * @note 00337 * @param 00338 * @retval 00339 */ 00340 uint16_t Enc28j60Eth::setReadPtr(memhandle handle, memaddress position, uint16_t len) 00341 { 00342 memblock* packet = handle == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[handle]; 00343 memaddress start = handle == UIP_RECEIVEBUFFERHANDLE && 00344 packet->begin + 00345 position > RXEND_INIT ? packet->begin + 00346 position - 00347 RXEND_INIT + 00348 RXSTART_INIT : packet->begin + 00349 position; 00350 00351 writeRegPair(ERDPTL, start); 00352 00353 if (len > packet->size - position) 00354 len = packet->size - position; 00355 return len; 00356 } 00357 00358 /** 00359 * @brief 00360 * @note 00361 * @param 00362 * @retval 00363 */ 00364 uint16_t Enc28j60Eth::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) 00365 { 00366 len = setReadPtr(handle, position, len); 00367 readBuffer(len, buffer); 00368 return len; 00369 } 00370 00371 /** 00372 * @brief 00373 * @note 00374 * @param 00375 * @retval 00376 */ 00377 uint16_t Enc28j60Eth::writePacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len) 00378 { 00379 memblock* packet = &blocks[handle]; 00380 uint16_t start = packet->begin + position; 00381 00382 writeRegPair(EWRPTL, start); 00383 00384 if (len > packet->size - position) 00385 len = packet->size - position; 00386 writeBuffer(len, buffer); 00387 return len; 00388 } 00389 00390 /** 00391 * @brief 00392 * @note 00393 * @param 00394 * @retval 00395 */ 00396 uint8_t Enc28j60Eth::readByte(uint16_t addr) 00397 { 00398 uint8_t result; 00399 00400 writeRegPair(ERDPTL, addr); 00401 00402 _cs = 0; 00403 00404 // issue read command 00405 _spi.write(ENC28J60_READ_BUF_MEM); 00406 00407 // read data 00408 result = _spi.write(0x00); 00409 00410 _cs = 1; 00411 00412 return(result); 00413 } 00414 00415 /** 00416 * @brief 00417 * @note 00418 * @param 00419 * @retval 00420 */ 00421 void Enc28j60Eth::writeByte(uint16_t addr, uint8_t data) 00422 { 00423 writeRegPair(EWRPTL, addr); 00424 00425 _cs = 0; 00426 00427 // issue write command 00428 _spi.write(ENC28J60_WRITE_BUF_MEM); 00429 00430 // write data 00431 _spi.write(data); 00432 00433 _cs = 1; 00434 } 00435 00436 /** 00437 * @brief 00438 * @note 00439 * @param 00440 * @retval 00441 */ 00442 void Enc28j60Eth::copyPacket 00443 ( 00444 memhandle dest_pkt, 00445 memaddress dest_pos, 00446 memhandle src_pkt, 00447 memaddress src_pos, 00448 uint16_t len 00449 ) 00450 { 00451 memblock* dest = &blocks[dest_pkt]; 00452 memblock* src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt]; 00453 memaddress start = src_pkt == UIP_RECEIVEBUFFERHANDLE && 00454 src->begin + 00455 src_pos > RXEND_INIT ? src->begin + 00456 src_pos - 00457 RXEND_INIT + 00458 RXSTART_INIT : src->begin + 00459 src_pos; 00460 enc28j60_mempool_block_move_callback(dest->begin + dest_pos, start, len); 00461 00462 // Move the RX read pointer to the start of the next received packet 00463 // This frees the memory we just read out 00464 //setERXRDPT(); 00465 } 00466 00467 /** 00468 * @brief 00469 * @note 00470 * @param 00471 * @retval 00472 */ 00473 void Enc28j60Eth::freePacket() 00474 { 00475 setERXRDPT(); 00476 } 00477 00478 /** 00479 * @brief 00480 * @note 00481 * @param 00482 * @retval 00483 */ 00484 uint8_t Enc28j60Eth::readOp(uint8_t op, uint8_t address) 00485 { 00486 uint8_t result; 00487 00488 _cs = 0; 00489 00490 // issue read command 00491 _spi.write(op | (address & ADDR_MASK)); 00492 00493 // read data 00494 result = _spi.write(0x00); 00495 00496 // do dummy read if needed (for mac and mii, see datasheet page 29) 00497 if (address & 0x80) 00498 result = _spi.write(0x00); 00499 00500 _cs = 1; 00501 return(result); 00502 } 00503 00504 /** 00505 * @brief 00506 * @note 00507 * @param 00508 * @retval 00509 */ 00510 void Enc28j60Eth::writeOp(uint8_t op, uint8_t address, uint8_t data) 00511 { 00512 _cs = 0; 00513 00514 // issue write command 00515 _spi.write(op | (address & ADDR_MASK)); 00516 00517 // write data 00518 _spi.write(data); 00519 00520 _cs = 1; 00521 } 00522 00523 /** 00524 * @brief 00525 * @note 00526 * @param 00527 * @retval 00528 */ 00529 void Enc28j60Eth::readBuffer(uint16_t len, uint8_t* data) 00530 { 00531 _cs = 0; 00532 00533 // issue read command 00534 _spi.write(ENC28J60_READ_BUF_MEM); 00535 00536 // read data 00537 while (len) { 00538 len--; 00539 *data = _spi.write(0x00); 00540 data++; 00541 } 00542 00543 *data = '\0'; 00544 00545 _cs = 1; 00546 } 00547 00548 /** 00549 * @brief 00550 * @note 00551 * @param 00552 * @retval 00553 */ 00554 void Enc28j60Eth::writeBuffer(uint16_t len, uint8_t* data) 00555 { 00556 _cs = 0; 00557 00558 // issue write command 00559 _spi.write(ENC28J60_WRITE_BUF_MEM); 00560 00561 // write data 00562 while (len) { 00563 len--; 00564 _spi.write(*data); 00565 data++; 00566 } 00567 00568 _cs = 1; 00569 } 00570 00571 /** 00572 * @brief 00573 * @note 00574 * @param 00575 * @retval 00576 */ 00577 void Enc28j60Eth::setBank(uint8_t address) 00578 { 00579 // set the bank (if needed) 00580 if ((address & BANK_MASK) != bank) { 00581 // set the bank 00582 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0)); 00583 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5); 00584 bank = (address & BANK_MASK); 00585 } 00586 } 00587 00588 /** 00589 * @brief 00590 * @note 00591 * @param 00592 * @retval 00593 */ 00594 uint8_t Enc28j60Eth::readReg(uint8_t address) 00595 { 00596 // set the bank 00597 setBank(address); 00598 00599 // do the read 00600 return readOp(ENC28J60_READ_CTRL_REG, address); 00601 } 00602 00603 /** 00604 * @brief 00605 * @note 00606 * @param 00607 * @retval 00608 */ 00609 void Enc28j60Eth::writeReg(uint8_t address, uint8_t data) 00610 { 00611 // set the bank 00612 setBank(address); 00613 00614 // do the write 00615 writeOp(ENC28J60_WRITE_CTRL_REG, address, data); 00616 } 00617 00618 /** 00619 * @brief 00620 * @note 00621 * @param 00622 * @retval 00623 */ 00624 void Enc28j60Eth::writeRegPair(uint8_t address, uint16_t data) 00625 { 00626 // set the bank 00627 setBank(address); 00628 00629 // do the write 00630 writeOp(ENC28J60_WRITE_CTRL_REG, address, (data & 0xFF)); 00631 writeOp(ENC28J60_WRITE_CTRL_REG, address + 1, (data) >> 8); 00632 } 00633 00634 /** 00635 * @brief 00636 * @note 00637 * @param 00638 * @retval 00639 */ 00640 void Enc28j60Eth::phyWrite(uint8_t address, uint16_t data) 00641 { 00642 // set the PHY register address 00643 writeReg(MIREGADR, address); 00644 00645 // write the PHY data 00646 writeRegPair(MIWRL, data); 00647 00648 // wait until the PHY write completes 00649 while (readReg(MISTAT) & MISTAT_BUSY) { 00650 wait_us(15); 00651 } 00652 } 00653 00654 /** 00655 * @brief 00656 * @note 00657 * @param 00658 * @retval 00659 */ 00660 uint16_t Enc28j60Eth::phyRead(uint8_t address) 00661 { 00662 writeReg(MIREGADR, address); 00663 writeReg(MICMD, MICMD_MIIRD); 00664 00665 // wait until the PHY read completes 00666 while (readReg(MISTAT) & MISTAT_BUSY) { 00667 wait_us(15); 00668 } //and MIRDH 00669 00670 writeReg(MICMD, 0); 00671 return(readReg(MIRDL) | readReg(MIRDH) << 8); 00672 } 00673 00674 /** 00675 * @brief 00676 * @note 00677 * @param 00678 * @retval 00679 */ 00680 void Enc28j60Eth::clkout(uint8_t clk) 00681 { 00682 //setup clkout: 2 is 12.5MHz: 00683 writeReg(ECOCON, clk & 0x7); 00684 } 00685 00686 // read the revision of the chip: 00687 uint8_t Enc28j60Eth::getrev() 00688 { 00689 return(readReg(EREVID)); 00690 } 00691 00692 /** 00693 * @brief 00694 * @note 00695 * @param 00696 * @retval 00697 */ 00698 uint16_t Enc28j60Eth::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len) 00699 { 00700 uint8_t spdr; 00701 uint16_t t; 00702 uint16_t i; 00703 00704 len = setReadPtr(handle, pos, len) - 1; 00705 _cs = 0; 00706 00707 // issue read command 00708 spdr = _spi.write(ENC28J60_READ_BUF_MEM); 00709 for (i = 0; i < len; i += 2) { 00710 // read data 00711 spdr = _spi.write(0x00); 00712 t = spdr << 8; 00713 spdr = _spi.write(0x00); 00714 t += spdr; 00715 sum += t; 00716 if (sum < t) { 00717 sum++; /* carry */ 00718 } 00719 } 00720 00721 if (i == len) { 00722 spdr = _spi.write(0x00); 00723 t = (spdr << 8) + 0; 00724 sum += t; 00725 if (sum < t) { 00726 sum++; /* carry */ 00727 } 00728 } 00729 00730 _cs = 1; 00731 00732 /* Return sum in host byte order. */ 00733 return sum; 00734 } 00735 00736 /** 00737 * @brief 00738 * @note 00739 * @param 00740 * @retval 00741 */ 00742 void Enc28j60Eth::powerOff() 00743 { 00744 writeOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN); 00745 #if MBED_MAJOR_VERSION == 2 00746 wait_ms(50); 00747 #else 00748 thread_sleep_for(50); 00749 #endif 00750 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS); 00751 #if MBED_MAJOR_VERSION == 2 00752 wait_ms(50); 00753 #else 00754 thread_sleep_for(50); 00755 #endif 00756 writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV); 00757 } 00758 00759 /** 00760 * @brief 00761 * @note 00762 * @param 00763 * @retval 00764 */ 00765 void Enc28j60Eth::powerOn() 00766 { 00767 writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV); 00768 #if MBED_MAJOR_VERSION == 2 00769 wait_ms(50); 00770 #else 00771 thread_sleep_for(50); 00772 #endif 00773 writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); 00774 #if MBED_MAJOR_VERSION == 2 00775 wait_ms(50); 00776 #else 00777 thread_sleep_for(50); 00778 #endif 00779 } 00780 00781 /** 00782 * @brief 00783 * @note 00784 * @param 00785 * @retval 00786 */ 00787 bool Enc28j60Eth::linkStatus() 00788 { 00789 return(phyRead(PHSTAT2) & 0x0400) > 0; 00790 }
Generated on Fri Jul 15 2022 22:55:10 by 1.7.2