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 // write MAC address inside the WZTOE MAC address register 00171 reg_wr_mac(SHAR, mac); 00172 #endif 00173 // set RX and TX buffer size 00174 #if 0 00175 for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00176 sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00177 sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00178 } 00179 #endif 00180 } 00181 00182 00183 bool WIZnet_Chip::close(int socket) 00184 { 00185 if (socket < 0) { 00186 return false; 00187 } 00188 // if not connected, return 00189 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00190 return true; 00191 } 00192 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00193 scmd(socket, DISCON); 00194 } 00195 scmd(socket, CLOSE); 00196 sreg<uint8_t>(socket, Sn_IR, 0xff); 00197 return true; 00198 } 00199 00200 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00201 { 00202 if (socket < 0) { 00203 return -1; 00204 } 00205 Timer t; 00206 t.reset(); 00207 t.start(); 00208 while(1) { 00209 //int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00210 // during the reading Sn_RX_RXR, it has the possible change of this register. 00211 // so read twice and get same value then use size information. 00212 int size, size2; 00213 do { 00214 size = sreg<uint16_t>(socket, Sn_RX_RSR); 00215 size2 = sreg<uint16_t>(socket, Sn_RX_RSR); 00216 } while (size != size2); 00217 00218 if (size > req_size) { 00219 return size; 00220 } 00221 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00222 break; 00223 } 00224 } 00225 return -1; 00226 } 00227 00228 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00229 { 00230 if (socket < 0) { 00231 return -1; 00232 } 00233 Timer t; 00234 t.reset(); 00235 t.start(); 00236 while(1) { 00237 //int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00238 // during the reading Sn_TX_FSR, it has the possible change of this register. 00239 // so read twice and get same value then use size information. 00240 int size, size2; 00241 do { 00242 size = sreg<uint16_t>(socket, Sn_TX_FSR); 00243 size2 = sreg<uint16_t>(socket, Sn_TX_FSR); 00244 } while (size != size2); 00245 00246 if (size > req_size) { 00247 return size; 00248 } 00249 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00250 break; 00251 } 00252 } 00253 return -1; 00254 } 00255 00256 int WIZnet_Chip::send(int socket, const char * str, int len) 00257 { 00258 if (socket < 0) { 00259 return -1; 00260 } 00261 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00262 uint8_t cntl_byte = (0x14 + (socket << 5)); 00263 spi_write(ptr, cntl_byte, (uint8_t*)str, len); 00264 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00265 scmd(socket, SEND); 00266 uint8_t tmp_Sn_IR; 00267 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00268 // @Jul.10, 2014 fix contant name, and udp sendto function. 00269 switch (sreg<uint8_t>(socket, Sn_SR)) { 00270 case SOCK_CLOSED : 00271 close(socket); 00272 return 0; 00273 //break; 00274 case SOCK_UDP : 00275 // ARP timeout is possible. 00276 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00277 sreg<uint8_t>(socket, Sn_IR, INT_TIMEOUT); 00278 return 0; 00279 } 00280 break; 00281 default : 00282 break; 00283 } 00284 } 00285 /* 00286 while ((sreg<uint8_t>(socket, Sn_IR) & INT_SEND_OK) != INT_SEND_OK) { 00287 if (sreg<uint8_t>(socket, Sn_SR) == CLOSED) { 00288 close(socket); 00289 return 0; 00290 } 00291 } 00292 */ 00293 sreg<uint8_t>(socket, Sn_IR, INT_SEND_OK); 00294 00295 return len; 00296 } 00297 00298 int WIZnet_Chip::recv(int socket, char* buf, int len) 00299 { 00300 if (socket < 0) { 00301 return -1; 00302 } 00303 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00304 uint8_t cntl_byte = (0x18 + (socket << 5)); 00305 spi_read(ptr, cntl_byte, (uint8_t*)buf, len); 00306 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00307 scmd(socket, RECV); 00308 return len; 00309 } 00310 00311 int WIZnet_Chip::new_socket() 00312 { 00313 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00314 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00315 return s; 00316 } 00317 } 00318 return -1; 00319 } 00320 00321 uint16_t WIZnet_Chip::new_port() 00322 { 00323 uint16_t port = rand(); 00324 port |= 49152; 00325 return port; 00326 } 00327 00328 bool WIZnet_Chip::link(int wait_time_ms) 00329 { 00330 Timer t; 00331 t.reset(); 00332 t.start(); 00333 while(1) { 00334 int is_link = ethernet_link(); 00335 00336 if (is_link) { 00337 return true; 00338 } 00339 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00340 break; 00341 } 00342 } 00343 return 0; 00344 } 00345 00346 void WIZnet_Chip::set_link(PHYMode phymode) 00347 { 00348 int speed = -1; 00349 int duplex = 0; 00350 00351 switch(phymode) { 00352 case AutoNegotiate : speed = -1; duplex = 0; break; 00353 case HalfDuplex10 : speed = 0; duplex = 0; break; 00354 case FullDuplex10 : speed = 0; duplex = 1; break; 00355 case HalfDuplex100 : speed = 1; duplex = 0; break; 00356 case FullDuplex100 : speed = 1; duplex = 1; break; 00357 } 00358 00359 ethernet_set_link(speed, duplex); 00360 } 00361 00362 void WIZnet_Chip::scmd(int socket, Command cmd) 00363 { 00364 sreg<uint8_t>(socket, Sn_CR, cmd); 00365 while(sreg<uint8_t>(socket, Sn_CR)); 00366 } 00367 00368 void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len) 00369 { 00370 cs = 0; 00371 spi->write(addr >> 8); 00372 spi->write(addr & 0xff); 00373 spi->write(cb); 00374 for(int i = 0; i < len; i++) { 00375 spi->write(buf[i]); 00376 } 00377 cs = 1; 00378 00379 #if DBG_SPI 00380 debug("[SPI]W %04x(%02x %d)", addr, cb, len); 00381 for(int i = 0; i < len; i++) { 00382 debug(" %02x", buf[i]); 00383 if (i > 16) { 00384 debug(" ..."); 00385 break; 00386 } 00387 } 00388 debug("\r\n"); 00389 #endif 00390 } 00391 00392 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len) 00393 { 00394 cs = 0; 00395 spi->write(addr >> 8); 00396 spi->write(addr & 0xff); 00397 spi->write(cb); 00398 for(int i = 0; i < len; i++) { 00399 buf[i] = spi->write(0); 00400 } 00401 cs = 1; 00402 00403 #if DBG_SPI 00404 debug("[SPI]R %04x(%02x %d)", addr, cb, len); 00405 for(int i = 0; i < len; i++) { 00406 debug(" %02x", buf[i]); 00407 if (i > 16) { 00408 debug(" ..."); 00409 break; 00410 } 00411 } 00412 debug("\r\n"); 00413 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) { 00414 wait_ms(200); 00415 } 00416 #endif 00417 } 00418 00419 uint32_t str_to_ip(const char* str) 00420 { 00421 uint32_t ip = 0; 00422 char* p = (char*)str; 00423 for(int i = 0; i < 4; i++) { 00424 ip |= atoi(p); 00425 p = strchr(p, '.'); 00426 if (p == NULL) { 00427 break; 00428 } 00429 ip <<= 8; 00430 p++; 00431 } 00432 return ip; 00433 } 00434 00435 void printfBytes(char* str, uint8_t* buf, int len) 00436 { 00437 printf("%s %d:", str, len); 00438 for(int i = 0; i < len; i++) { 00439 printf(" %02x", buf[i]); 00440 } 00441 printf("\n"); 00442 } 00443 00444 void printHex(uint8_t* buf, int len) 00445 { 00446 for(int i = 0; i < len; i++) { 00447 if ((i%16) == 0) { 00448 printf("%p", buf+i); 00449 } 00450 printf(" %02x", buf[i]); 00451 if ((i%16) == 15) { 00452 printf("\n"); 00453 } 00454 } 00455 printf("\n"); 00456 } 00457 00458 void debug_hex(uint8_t* buf, int len) 00459 { 00460 for(int i = 0; i < len; i++) { 00461 if ((i%16) == 0) { 00462 debug("%p", buf+i); 00463 } 00464 debug(" %02x", buf[i]); 00465 if ((i%16) == 15) { 00466 debug("\n"); 00467 } 00468 } 00469 debug("\n"); 00470 } 00471 00472 int WIZnet_Chip::ethernet_link(void) { 00473 int val = getPHYCFGR(); 00474 return (val&0x01); 00475 } 00476 00477 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00478 uint32_t val=0; 00479 if((speed < 0) || (speed > 1)) { 00480 val = (PHYCFGR_OPMDC_ALLA)<<3; 00481 } else { 00482 val = (((speed&0x01)<<1)+ (duplex&0x01))<<3; 00483 } 00484 setPHYCFGR((uint8_t)(PHYCFGR_RST&(PHYCFGR_OPMD|val))); 00485 wait(0.2); 00486 setPHYCFGR((uint8_t)((~PHYCFGR_RST)|(PHYCFGR_OPMD|val))); 00487 wait(0.2); 00488 } 00489 00490 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) { 00491 spi_read(addr, 0x00, data, 6); 00492 } 00493 00494 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) { 00495 uint8_t buf[4]; 00496 char* p = (char*)ip; 00497 for(int i = 0; i < 4; i++) { 00498 buf[i] = atoi(p); 00499 p = strchr(p, '.'); 00500 if (p == NULL) { 00501 break; 00502 } 00503 p++; 00504 } 00505 spi_write(addr, cb, buf, sizeof(buf)); 00506 } 00507 00508 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00509 reg_wr_ip(addr, (0x0C + (socket << 5)), ip); 00510 } 00511 00512 void WIZnet_Chip::reg_rd_ip_byte(uint16_t addr, uint8_t* data) { 00513 spi_read(addr, 0x00, data, 4); 00514 } 00515 00516 void WIZnet_Chip::reg_wr_ip_byte(uint16_t addr, uint8_t* data) { 00517 spi_write(addr, 0x04, data, 4); 00518 } 00519 00520 00521 #endif 00522
Generated on Wed Jul 13 2022 18:34:07 by
1.7.2
