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
W5200.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_W5200 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("[WIZnet_Chip:DBG]"x"\r\n", ##__VA_ARGS__); 00030 #define WARN(x, ...) debug("[WIZnet_Chip:WARN]"x"\r\n", ##__VA_ARGS__); 00031 #define ERR(x, ...) debug("[WIZnet_Chip: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("[WIZnet_Chip: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 } 00056 00057 WIZnet_Chip::WIZnet_Chip(SPI* spi, PinName _cs, PinName _reset): 00058 cs(_cs), reset_pin(_reset) 00059 { 00060 this->spi = spi; 00061 cs = 1; 00062 reset_pin = 1; 00063 inst = this; 00064 } 00065 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 00106 bool WIZnet_Chip::is_fin_received(int socket) 00107 { 00108 uint8_t tmpSn_SR; 00109 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00110 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00111 if (tmpSn_SR == SOCK_CLOSE_WAIT) { 00112 return true; 00113 } 00114 return false; 00115 } 00116 00117 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip) 00118 { 00119 uint32_t addr = str_to_ip(host); 00120 char buf[17]; 00121 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff); 00122 if (strcmp(buf, host) == 0) { 00123 *ip = addr; 00124 return true; 00125 } 00126 DNSClient client; 00127 if(client.lookup(host)) { 00128 *ip = client.ip; 00129 return true; 00130 } 00131 return false; 00132 } 00133 00134 bool WIZnet_Chip::disconnect() 00135 { 00136 return true; 00137 } 00138 00139 bool WIZnet_Chip::is_connected(int socket) 00140 { 00141 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00142 return true; 00143 } 00144 return false; 00145 } 00146 00147 void WIZnet_Chip::reset() 00148 { 00149 reset_pin = 1; 00150 reset_pin = 0; 00151 wait_us(2); // 2us 00152 reset_pin = 1; 00153 wait_ms(150); // 150ms 00154 00155 reg_wr<uint8_t>(MR, 1<<7); 00156 00157 reg_wr_mac(SHAR, mac); 00158 } 00159 00160 bool WIZnet_Chip::close(int socket) 00161 { 00162 if (socket < 0) { 00163 return false; 00164 } 00165 // if not connected, return 00166 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00167 return true; 00168 } 00169 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00170 scmd(socket, DISCON); 00171 } 00172 scmd(socket, CLOSE); 00173 sreg<uint8_t>(socket, Sn_IR, 0xff); 00174 return true; 00175 } 00176 00177 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00178 { 00179 if (socket < 0) { 00180 return -1; 00181 } 00182 Timer t; 00183 t.reset(); 00184 t.start(); 00185 while(1) { 00186 //int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00187 // during the reading Sn_RX_RXR, it has the possible change of this register. 00188 // so read twice and get same value then use size information. 00189 int size, size2; 00190 do { 00191 size = sreg<uint16_t>(socket, Sn_RX_RSR); 00192 size2 = sreg<uint16_t>(socket, Sn_RX_RSR); 00193 } while (size != size2); 00194 00195 if (size > req_size) { 00196 return size; 00197 } 00198 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00199 break; 00200 } 00201 } 00202 return -1; 00203 } 00204 00205 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00206 { 00207 if (socket < 0) { 00208 return -1; 00209 } 00210 Timer t; 00211 t.reset(); 00212 t.start(); 00213 while(1) { 00214 //int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00215 // during the reading Sn_TX_FSR, it has the possible change of this register. 00216 // so read twice and get same value then use size information. 00217 int size, size2; 00218 do { 00219 size = sreg<uint16_t>(socket, Sn_TX_FSR); 00220 size2 = sreg<uint16_t>(socket, Sn_TX_FSR); 00221 } while (size != size2); 00222 00223 if (size > req_size) { 00224 return size; 00225 } 00226 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00227 break; 00228 } 00229 } 00230 return -1; 00231 } 00232 00233 int WIZnet_Chip::send(int socket, const char * str, int len) 00234 { 00235 if (socket < 0) { 00236 return -1; 00237 } 00238 uint16_t base = 0x8000 + socket * 0x800; 00239 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00240 uint16_t dst = base + (ptr&(0x800-1)); 00241 if ((dst + len) > (base+0x800)) { 00242 int len2 = base + 0x800 - dst; 00243 spi_write(dst, (uint8_t*)str, len2); 00244 spi_write(base, (uint8_t*)str+len2, len-len2); 00245 } else { 00246 spi_write(dst, (uint8_t*)str, len); 00247 } 00248 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00249 scmd(socket, SEND); 00250 return len; 00251 } 00252 00253 int WIZnet_Chip::recv(int socket, char* buf, int len) 00254 { 00255 if (socket < 0) { 00256 return -1; 00257 } 00258 uint16_t base = 0xc000 + socket * 0x800; 00259 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00260 uint16_t src = base + (ptr&(0x800-1)); 00261 if ((src + len) > (base+0x800)) { 00262 int len2 = base + 0x800 - src; 00263 spi_read(src, (uint8_t*)buf, len2); 00264 spi_read(base, (uint8_t*)buf+len2, len-len2); 00265 } else { 00266 spi_read(src, (uint8_t*)buf, len); 00267 } 00268 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00269 scmd(socket, RECV); 00270 return len; 00271 } 00272 00273 int WIZnet_Chip::new_socket() 00274 { 00275 for(int s = 0; s < 8; s++) { 00276 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00277 return s; 00278 } 00279 } 00280 return -1; 00281 } 00282 00283 uint16_t WIZnet_Chip::new_port() 00284 { 00285 uint16_t port = rand(); 00286 port |= 49152; 00287 return port; 00288 } 00289 00290 void WIZnet_Chip::scmd(int socket, Command cmd) 00291 { 00292 sreg<uint8_t>(socket, Sn_CR, cmd); 00293 while(sreg<uint8_t>(socket, Sn_CR)); 00294 } 00295 00296 void WIZnet_Chip::spi_write(uint16_t addr, const uint8_t *buf, uint16_t len) 00297 { 00298 cs = 0; 00299 spi->write(addr >> 8); 00300 spi->write(addr & 0xff); 00301 spi->write((0x80 | ((len & 0x7f00) >> 8))); 00302 spi->write(len & 0xff); 00303 for(int i = 0; i < len; i++) { 00304 spi->write(buf[i]); 00305 } 00306 cs = 1; 00307 00308 #if DBG_SPI 00309 debug("[SPI]W %04x(%d)", addr, len); 00310 for(int i = 0; i < len; i++) { 00311 debug(" %02x", buf[i]); 00312 if (i > 16) { 00313 debug(" ..."); 00314 break; 00315 } 00316 } 00317 debug("\r\n"); 00318 #endif 00319 } 00320 00321 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t *buf, uint16_t len) 00322 { 00323 cs = 0; 00324 spi->write(addr >> 8); 00325 spi->write(addr & 0xff); 00326 spi->write((0x00 | ((len & 0x7f00) >> 8))); 00327 spi->write(len & 0xff); 00328 for(int i = 0; i < len; i++) { 00329 buf[i] = spi->write(0); 00330 } 00331 cs = 1; 00332 00333 #if DBG_SPI 00334 debug("[SPI]R %04x(%d)", addr, len); 00335 for(int i = 0; i < len; i++) { 00336 debug(" %02x", buf[i]); 00337 if (i > 16) { 00338 debug(" ..."); 00339 break; 00340 } 00341 } 00342 debug("\r\n"); 00343 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) { 00344 wait_ms(200); 00345 } 00346 #endif 00347 } 00348 00349 uint32_t str_to_ip(const char* str) 00350 { 00351 uint32_t ip = 0; 00352 char* p = (char*)str; 00353 for(int i = 0; i < 4; i++) { 00354 ip |= atoi(p); 00355 p = strchr(p, '.'); 00356 if (p == NULL) { 00357 break; 00358 } 00359 ip <<= 8; 00360 p++; 00361 } 00362 return ip; 00363 } 00364 00365 void printfBytes(char* str, uint8_t* buf, int len) 00366 { 00367 printf("%s %d:", str, len); 00368 for(int i = 0; i < len; i++) { 00369 printf(" %02x", buf[i]); 00370 } 00371 printf("\n"); 00372 } 00373 00374 void printHex(uint8_t* buf, int len) 00375 { 00376 for(int i = 0; i < len; i++) { 00377 if ((i%16) == 0) { 00378 printf("%p", buf+i); 00379 } 00380 printf(" %02x", buf[i]); 00381 if ((i%16) == 15) { 00382 printf("\n"); 00383 } 00384 } 00385 printf("\n"); 00386 } 00387 00388 void debug_hex(uint8_t* buf, int len) 00389 { 00390 for(int i = 0; i < len; i++) { 00391 if ((i%16) == 0) { 00392 debug("%p", buf+i); 00393 } 00394 debug(" %02x", buf[i]); 00395 if ((i%16) == 15) { 00396 debug("\n"); 00397 } 00398 } 00399 debug("\n"); 00400 } 00401 00402 #endif
Generated on Fri Jul 15 2022 13:48:35 by
