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