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