Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of WIZnetInterface by
W5500.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 #include "eth_arch.h" 00019 #if (not defined TARGET_WIZwiki_W7500) && (not defined TARGET_WIZwiki_W7500P) && (not defined TARGET_WIZwiki_W7500ECO) 00020 00021 00022 00023 #include "mbed.h" 00024 #include "mbed_debug.h" 00025 #include "DNSClient.h" 00026 00027 00028 //Debug is disabled by default 00029 #if 0 00030 #define DBG(...) do{debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0); 00031 //#define DBG(x, ...) debug("[W5500:DBG]"x"\r\n", ##__VA_ARGS__); 00032 #define WARN(x, ...) debug("[W5500:WARN]"x"\r\n", ##__VA_ARGS__); 00033 #define ERR(x, ...) debug("[W5500:ERR]"x"\r\n", ##__VA_ARGS__); 00034 #else 00035 #define DBG(x, ...) 00036 #define WARN(x, ...) 00037 #define ERR(x, ...) 00038 #endif 00039 00040 #if 1 00041 #define INFO(x, ...) debug("[W5500:INFO]"x"\r\n", ##__VA_ARGS__); 00042 #else 00043 #define INFO(x, ...) 00044 #endif 00045 00046 #define DBG_SPI 0 00047 00048 WIZnet_Chip* WIZnet_Chip::inst; 00049 00050 WIZnet_Chip::WIZnet_Chip(PinName mosi, PinName miso, PinName sclk, PinName _cs, PinName _reset): 00051 cs(_cs), reset_pin(_reset) 00052 { 00053 spi = new SPI(mosi, miso, sclk); 00054 cs = 1; 00055 reset_pin = 1; 00056 inst = this; 00057 sock_any_port = SOCK_ANY_PORT_NUM; 00058 } 00059 00060 WIZnet_Chip::WIZnet_Chip(SPI* spi, PinName _cs, PinName _reset): 00061 cs(_cs), reset_pin(_reset) 00062 { 00063 this->spi = spi; 00064 cs = 1; 00065 reset_pin = 1; 00066 inst = this; 00067 sock_any_port = SOCK_ANY_PORT_NUM; 00068 } 00069 00070 bool WIZnet_Chip::setmac() 00071 { 00072 00073 for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]); 00074 00075 return true; 00076 } 00077 00078 // Set the IP 00079 bool WIZnet_Chip::setip() 00080 { 00081 reg_wr<uint32_t>(SIPR, ip); 00082 reg_wr<uint32_t>(GAR, gateway); 00083 reg_wr<uint32_t>(SUBR, netmask); 00084 return true; 00085 } 00086 00087 bool WIZnet_Chip::setProtocol(int socket, Protocol p) 00088 { 00089 if (socket < 0) { 00090 return false; 00091 } 00092 sreg<uint8_t>(socket, Sn_MR, p); 00093 return true; 00094 } 00095 00096 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms) 00097 { 00098 if (socket < 0) { 00099 return false; 00100 } 00101 sreg<uint8_t>(socket, Sn_MR, TCP); 00102 scmd(socket, OPEN); 00103 sreg_ip(socket, Sn_DIPR, host); 00104 sreg<uint16_t>(socket, Sn_DPORT, port); 00105 sreg<uint16_t>(socket, Sn_PORT, new_port()); 00106 scmd(socket, CONNECT); 00107 Timer t; 00108 t.reset(); 00109 t.start(); 00110 while(!is_connected(socket)) { 00111 if (t.read_ms() > timeout_ms) { 00112 return false; 00113 } 00114 } 00115 return true; 00116 } 00117 00118 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip) 00119 { 00120 uint32_t addr = str_to_ip(host); 00121 char buf[17]; 00122 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff); 00123 if (strcmp(buf, host) == 0) { 00124 *ip = addr; 00125 return true; 00126 } 00127 DNSClient client; 00128 if(client.lookup(host)) { 00129 *ip = client.ip; 00130 return true; 00131 } 00132 return false; 00133 } 00134 00135 bool WIZnet_Chip::disconnect() 00136 { 00137 return true; 00138 } 00139 00140 bool WIZnet_Chip::is_connected(int socket) 00141 { 00142 /* 00143 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00144 return true; 00145 } 00146 */ 00147 uint8_t tmpSn_SR; 00148 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00149 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00150 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) { 00151 return true; 00152 } 00153 return false; 00154 } 00155 00156 // Reset the chip & set the buffer 00157 void WIZnet_Chip::reset() 00158 { 00159 #if defined(USE_WIZ550IO_MAC) 00160 //read the MAC address inside the module 00161 reg_rd_mac(SHAR, mac); 00162 #endif 00163 // hw reset 00164 reset_pin = 1; 00165 reset_pin = 0; 00166 wait_us(500); // 500us (w5500) 00167 reset_pin = 1; 00168 wait_ms(400); // 400ms (w5500) 00169 #if defined(USE_WIZ550IO_MAC) 00170 #endif 00171 00172 // set RX and TX buffer size 00173 #if 0 00174 for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00175 sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00176 sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00177 } 00178 #endif 00179 00180 // write MAC address inside the WZTOE MAC address register 00181 reg_wr_mac(SHAR, mac); 00182 00183 } 00184 00185 00186 bool WIZnet_Chip::close(int socket) 00187 { 00188 if (socket < 0) { 00189 return false; 00190 } 00191 // if not connected, return 00192 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00193 return true; 00194 } 00195 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00196 scmd(socket, DISCON); 00197 } 00198 scmd(socket, CLOSE); 00199 sreg<uint8_t>(socket, Sn_IR, 0xff); 00200 return true; 00201 } 00202 00203 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00204 { 00205 if (socket < 0) { 00206 return -1; 00207 } 00208 Timer t; 00209 t.reset(); 00210 t.start(); 00211 while(1) { 00212 //int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00213 // during the reading Sn_RX_RXR, it has the possible change of this register. 00214 // so read twice and get same value then use size information. 00215 int size, size2; 00216 do { 00217 size = sreg<uint16_t>(socket, Sn_RX_RSR); 00218 size2 = sreg<uint16_t>(socket, Sn_RX_RSR); 00219 } while (size != size2); 00220 00221 if (size > req_size) { 00222 return size; 00223 } 00224 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00225 break; 00226 } 00227 } 00228 return -1; 00229 } 00230 00231 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00232 { 00233 if (socket < 0) { 00234 return -1; 00235 } 00236 Timer t; 00237 t.reset(); 00238 t.start(); 00239 while(1) { 00240 //int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00241 // during the reading Sn_TX_FSR, it has the possible change of this register. 00242 // so read twice and get same value then use size information. 00243 int size, size2; 00244 do { 00245 size = sreg<uint16_t>(socket, Sn_TX_FSR); 00246 size2 = sreg<uint16_t>(socket, Sn_TX_FSR); 00247 } while (size != size2); 00248 00249 if (size > req_size) { 00250 return size; 00251 } 00252 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00253 break; 00254 } 00255 } 00256 return -1; 00257 } 00258 00259 int WIZnet_Chip::send(int socket, const char * str, int len) 00260 { 00261 if (socket < 0) { 00262 return -1; 00263 } 00264 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00265 uint8_t cntl_byte = (0x14 + (socket << 5)); 00266 spi_write(ptr, cntl_byte, (uint8_t*)str, len); 00267 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00268 scmd(socket, SEND); 00269 uint8_t tmp_Sn_IR; 00270 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00271 // @Jul.10, 2014 fix contant name, and udp sendto function. 00272 switch (sreg<uint8_t>(socket, Sn_SR)) { 00273 case SOCK_CLOSED : 00274 close(socket); 00275 return 0; 00276 //break; 00277 case SOCK_UDP : 00278 // ARP timeout is possible. 00279 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00280 sreg<uint8_t>(socket, Sn_IR, INT_TIMEOUT); 00281 return 0; 00282 } 00283 break; 00284 default : 00285 break; 00286 } 00287 } 00288 /* 00289 while ((sreg<uint8_t>(socket, Sn_IR) & INT_SEND_OK) != INT_SEND_OK) { 00290 if (sreg<uint8_t>(socket, Sn_SR) == CLOSED) { 00291 close(socket); 00292 return 0; 00293 } 00294 } 00295 */ 00296 sreg<uint8_t>(socket, Sn_IR, INT_SEND_OK); 00297 00298 return len; 00299 } 00300 00301 int WIZnet_Chip::recv(int socket, char* buf, int len) 00302 { 00303 if (socket < 0) { 00304 return -1; 00305 } 00306 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00307 uint8_t cntl_byte = (0x18 + (socket << 5)); 00308 spi_read(ptr, cntl_byte, (uint8_t*)buf, len); 00309 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00310 scmd(socket, RECV); 00311 return len; 00312 } 00313 00314 int WIZnet_Chip::new_socket() 00315 { 00316 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00317 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00318 return s; 00319 } 00320 } 00321 return -1; 00322 } 00323 00324 uint16_t WIZnet_Chip::new_port() 00325 { 00326 uint16_t port = rand(); 00327 port |= 49152; 00328 return port; 00329 } 00330 00331 bool WIZnet_Chip::link(int wait_time_ms) 00332 { 00333 Timer t; 00334 t.reset(); 00335 t.start(); 00336 while(1) { 00337 int is_link = ethernet_link(); 00338 00339 if (is_link) { 00340 return true; 00341 } 00342 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00343 break; 00344 } 00345 } 00346 return 0; 00347 } 00348 00349 void WIZnet_Chip::set_link(PHYMode phymode) 00350 { 00351 int speed = -1; 00352 int duplex = 0; 00353 00354 switch(phymode) { 00355 case AutoNegotiate : speed = -1; duplex = 0; break; 00356 case HalfDuplex10 : speed = 0; duplex = 0; break; 00357 case FullDuplex10 : speed = 0; duplex = 1; break; 00358 case HalfDuplex100 : speed = 1; duplex = 0; break; 00359 case FullDuplex100 : speed = 1; duplex = 1; break; 00360 } 00361 00362 ethernet_set_link(speed, duplex); 00363 } 00364 00365 void WIZnet_Chip::scmd(int socket, Command cmd) 00366 { 00367 sreg<uint8_t>(socket, Sn_CR, cmd); 00368 while(sreg<uint8_t>(socket, Sn_CR)); 00369 } 00370 00371 void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len) 00372 { 00373 cs = 0; 00374 spi->write(addr >> 8); 00375 spi->write(addr & 0xff); 00376 spi->write(cb); 00377 for(int i = 0; i < len; i++) { 00378 spi->write(buf[i]); 00379 } 00380 cs = 1; 00381 00382 #if DBG_SPI 00383 debug("[SPI]W %04x(%02x %d)", addr, cb, len); 00384 for(int i = 0; i < len; i++) { 00385 debug(" %02x", buf[i]); 00386 if (i > 16) { 00387 debug(" ..."); 00388 break; 00389 } 00390 } 00391 debug("\r\n"); 00392 #endif 00393 } 00394 00395 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len) 00396 { 00397 cs = 0; 00398 spi->write(addr >> 8); 00399 spi->write(addr & 0xff); 00400 spi->write(cb); 00401 for(int i = 0; i < len; i++) { 00402 buf[i] = spi->write(0); 00403 } 00404 cs = 1; 00405 00406 #if DBG_SPI 00407 debug("[SPI]R %04x(%02x %d)", addr, cb, len); 00408 for(int i = 0; i < len; i++) { 00409 debug(" %02x", buf[i]); 00410 if (i > 16) { 00411 debug(" ..."); 00412 break; 00413 } 00414 } 00415 debug("\r\n"); 00416 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) { 00417 wait_ms(200); 00418 } 00419 #endif 00420 } 00421 00422 uint32_t str_to_ip(const char* str) 00423 { 00424 uint32_t ip = 0; 00425 char* p = (char*)str; 00426 for(int i = 0; i < 4; i++) { 00427 ip |= atoi(p); 00428 p = strchr(p, '.'); 00429 if (p == NULL) { 00430 break; 00431 } 00432 ip <<= 8; 00433 p++; 00434 } 00435 return ip; 00436 } 00437 00438 void printfBytes(char* str, uint8_t* buf, int len) 00439 { 00440 printf("%s %d:", str, len); 00441 for(int i = 0; i < len; i++) { 00442 printf(" %02x", buf[i]); 00443 } 00444 printf("\n"); 00445 } 00446 00447 void printHex(uint8_t* buf, int len) 00448 { 00449 for(int i = 0; i < len; i++) { 00450 if ((i%16) == 0) { 00451 printf("%p", buf+i); 00452 } 00453 printf(" %02x", buf[i]); 00454 if ((i%16) == 15) { 00455 printf("\n"); 00456 } 00457 } 00458 printf("\n"); 00459 } 00460 00461 void debug_hex(uint8_t* buf, int len) 00462 { 00463 for(int i = 0; i < len; i++) { 00464 if ((i%16) == 0) { 00465 debug("%p", buf+i); 00466 } 00467 debug(" %02x", buf[i]); 00468 if ((i%16) == 15) { 00469 debug("\n"); 00470 } 00471 } 00472 debug("\n"); 00473 } 00474 00475 int WIZnet_Chip::ethernet_link(void) { 00476 int val = getPHYCFGR(); 00477 return (val&0x01); 00478 } 00479 00480 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00481 uint32_t val=0; 00482 if((speed < 0) || (speed > 1)) { 00483 val = (PHYCFGR_OPMDC_ALLA)<<3; 00484 } else { 00485 val = (((speed&0x01)<<1)+ (duplex&0x01))<<3; 00486 } 00487 setPHYCFGR((uint8_t)(PHYCFGR_RST&(PHYCFGR_OPMD|val))); 00488 wait(0.2); 00489 setPHYCFGR((uint8_t)((~PHYCFGR_RST)|(PHYCFGR_OPMD|val))); 00490 wait(0.2); 00491 } 00492 00493 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) { 00494 spi_read(addr, 0x00, data, 6); 00495 } 00496 00497 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) { 00498 uint8_t buf[4]; 00499 char* p = (char*)ip; 00500 for(int i = 0; i < 4; i++) { 00501 buf[i] = atoi(p); 00502 p = strchr(p, '.'); 00503 if (p == NULL) { 00504 break; 00505 } 00506 p++; 00507 } 00508 spi_write(addr, cb, buf, sizeof(buf)); 00509 } 00510 00511 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00512 reg_wr_ip(addr, (0x0C + (socket << 5)), ip); 00513 } 00514 00515 void WIZnet_Chip::reg_rd_ip_byte(uint16_t addr, uint8_t* data) { 00516 spi_read(addr, 0x00, data, 4); 00517 } 00518 00519 void WIZnet_Chip::reg_wr_ip_byte(uint16_t addr, uint8_t* data) { 00520 spi_write(addr, 0x04, data, 4); 00521 } 00522 00523 00524 #endif 00525
Generated on Tue Jul 12 2022 20:38:48 by
1.7.2
