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