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 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 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00130 return true; 00131 } 00132 return false; 00133 } 00134 00135 void WIZnet_Chip::reset() 00136 { 00137 reset_pin = 1; 00138 reset_pin = 0; 00139 wait_us(2); // 2us 00140 reset_pin = 1; 00141 wait_ms(150); // 150ms 00142 00143 reg_wr<uint8_t>(MR, 1<<7); 00144 00145 reg_wr_mac(SHAR, mac); 00146 } 00147 00148 bool WIZnet_Chip::close(int socket) 00149 { 00150 if (socket < 0) { 00151 return false; 00152 } 00153 // if not connected, return 00154 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00155 return true; 00156 } 00157 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00158 scmd(socket, DISCON); 00159 } 00160 scmd(socket, CLOSE); 00161 sreg<uint8_t>(socket, Sn_IR, 0xff); 00162 return true; 00163 } 00164 00165 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00166 { 00167 if (socket < 0) { 00168 return -1; 00169 } 00170 Timer t; 00171 t.reset(); 00172 t.start(); 00173 while(1) { 00174 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00175 if (size > req_size) { 00176 return size; 00177 } 00178 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00179 break; 00180 } 00181 } 00182 return -1; 00183 } 00184 00185 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00186 { 00187 if (socket < 0) { 00188 return -1; 00189 } 00190 Timer t; 00191 t.reset(); 00192 t.start(); 00193 while(1) { 00194 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 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::send(int socket, const char * str, int len) 00206 { 00207 if (socket < 0) { 00208 return -1; 00209 } 00210 uint16_t base = 0x8000 + socket * 0x800; 00211 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00212 uint16_t dst = base + (ptr&(0x800-1)); 00213 if ((dst + len) > (base+0x800)) { 00214 int len2 = base + 0x800 - dst; 00215 spi_write(dst, (uint8_t*)str, len2); 00216 spi_write(base, (uint8_t*)str+len2, len-len2); 00217 } else { 00218 spi_write(dst, (uint8_t*)str, len); 00219 } 00220 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00221 scmd(socket, SEND); 00222 return len; 00223 } 00224 00225 int WIZnet_Chip::recv(int socket, char* buf, int len) 00226 { 00227 if (socket < 0) { 00228 return -1; 00229 } 00230 uint16_t base = 0xc000 + socket * 0x800; 00231 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00232 uint16_t src = base + (ptr&(0x800-1)); 00233 if ((src + len) > (base+0x800)) { 00234 int len2 = base + 0x800 - src; 00235 spi_read(src, (uint8_t*)buf, len2); 00236 spi_read(base, (uint8_t*)buf+len2, len-len2); 00237 } else { 00238 spi_read(src, (uint8_t*)buf, len); 00239 } 00240 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00241 scmd(socket, RECV); 00242 return len; 00243 } 00244 00245 int WIZnet_Chip::new_socket() 00246 { 00247 for(int s = 0; s < 8; s++) { 00248 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00249 return s; 00250 } 00251 } 00252 return -1; 00253 } 00254 00255 uint16_t WIZnet_Chip::new_port() 00256 { 00257 uint16_t port = rand(); 00258 port |= 49152; 00259 return port; 00260 } 00261 00262 void WIZnet_Chip::scmd(int socket, Command cmd) 00263 { 00264 sreg<uint8_t>(socket, Sn_CR, cmd); 00265 while(sreg<uint8_t>(socket, Sn_CR)); 00266 } 00267 00268 void WIZnet_Chip::spi_write(uint16_t addr, const uint8_t *buf, uint16_t len) 00269 { 00270 cs = 0; 00271 spi->write(addr >> 8); 00272 spi->write(addr & 0xff); 00273 spi->write((0x80 | ((len & 0x7f00) >> 8))); 00274 spi->write(len & 0xff); 00275 for(int i = 0; i < len; i++) { 00276 spi->write(buf[i]); 00277 } 00278 cs = 1; 00279 00280 #if DBG_SPI 00281 debug("[SPI]W %04x(%d)", addr, len); 00282 for(int i = 0; i < len; i++) { 00283 debug(" %02x", buf[i]); 00284 if (i > 16) { 00285 debug(" ..."); 00286 break; 00287 } 00288 } 00289 debug("\r\n"); 00290 #endif 00291 } 00292 00293 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t *buf, uint16_t len) 00294 { 00295 cs = 0; 00296 spi->write(addr >> 8); 00297 spi->write(addr & 0xff); 00298 spi->write((0x00 | ((len & 0x7f00) >> 8))); 00299 spi->write(len & 0xff); 00300 for(int i = 0; i < len; i++) { 00301 buf[i] = spi->write(0); 00302 } 00303 cs = 1; 00304 00305 #if DBG_SPI 00306 debug("[SPI]R %04x(%d)", addr, len); 00307 for(int i = 0; i < len; i++) { 00308 debug(" %02x", buf[i]); 00309 if (i > 16) { 00310 debug(" ..."); 00311 break; 00312 } 00313 } 00314 debug("\r\n"); 00315 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) { 00316 wait_ms(200); 00317 } 00318 #endif 00319 } 00320 00321 uint32_t str_to_ip(const char* str) 00322 { 00323 uint32_t ip = 0; 00324 char* p = (char*)str; 00325 for(int i = 0; i < 4; i++) { 00326 ip |= atoi(p); 00327 p = strchr(p, '.'); 00328 if (p == NULL) { 00329 break; 00330 } 00331 ip <<= 8; 00332 p++; 00333 } 00334 return ip; 00335 } 00336 00337 void printfBytes(char* str, uint8_t* buf, int len) 00338 { 00339 printf("%s %d:", str, len); 00340 for(int i = 0; i < len; i++) { 00341 printf(" %02x", buf[i]); 00342 } 00343 printf("\n"); 00344 } 00345 00346 void printHex(uint8_t* buf, int len) 00347 { 00348 for(int i = 0; i < len; i++) { 00349 if ((i%16) == 0) { 00350 printf("%p", buf+i); 00351 } 00352 printf(" %02x", buf[i]); 00353 if ((i%16) == 15) { 00354 printf("\n"); 00355 } 00356 } 00357 printf("\n"); 00358 } 00359 00360 void debug_hex(uint8_t* buf, int len) 00361 { 00362 for(int i = 0; i < len; i++) { 00363 if ((i%16) == 0) { 00364 debug("%p", buf+i); 00365 } 00366 debug(" %02x", buf[i]); 00367 if ((i%16) == 15) { 00368 debug("\n"); 00369 } 00370 } 00371 debug("\n"); 00372 } 00373 00374 #endif
Generated on Thu Jul 14 2022 08:03:44 by
