WIZ820io(W5200) network interface, EthernetInterface compatible.
Dependents: Seeed_Ethernet_Shield_V2_HelloWorld Seeed_Ethernet_Shield Cayenne-WIZ820ioInterface Seeed_Ethernet_Shield
Fork of WiflyInterface by
WIZ820io.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 "WIZ820io.h" 00022 #include "DNSClient.h" 00023 00024 //Debug is disabled by default 00025 #if 0 00026 #define DBG(...) do{debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0); 00027 //#define DBG(x, ...) debug("[WIZ820io:DBG]"x"\r\n", ##__VA_ARGS__); 00028 #define WARN(x, ...) debug("[WIZ820io:WARN]"x"\r\n", ##__VA_ARGS__); 00029 #define ERR(x, ...) debug("[WIZ820io:ERR]"x"\r\n", ##__VA_ARGS__); 00030 #else 00031 #define DBG(x, ...) 00032 #define WARN(x, ...) 00033 #define ERR(x, ...) 00034 #endif 00035 00036 #if 1 00037 #define INFO(x, ...) debug("[WIZ820io:INFO]"x"\r\n", ##__VA_ARGS__); 00038 #else 00039 #define INFO(x, ...) 00040 #endif 00041 00042 #define DBG_SPI 0 00043 00044 WIZ820io* WIZ820io::inst; 00045 00046 WIZ820io::WIZ820io(PinName mosi, PinName miso, PinName sclk, PinName _cs, PinName _reset): 00047 cs(_cs), reset_pin(_reset) 00048 { 00049 spi = new SPI(mosi, miso, sclk); 00050 cs = 1; 00051 reset_pin = 1; 00052 inst = this; 00053 } 00054 00055 WIZ820io::WIZ820io(SPI* spi, PinName _cs, PinName _reset): 00056 cs(_cs), reset_pin(_reset) 00057 { 00058 this->spi = spi; 00059 cs = 1; 00060 reset_pin = 1; 00061 inst = this; 00062 } 00063 00064 bool WIZ820io::join() 00065 { 00066 reg_wr<uint32_t>(SIPR, ip); 00067 reg_wr<uint32_t>(GAR, gateway); 00068 reg_wr<uint32_t>(SUBR, netmask); 00069 return true; 00070 } 00071 00072 bool WIZ820io::setProtocol(int socket, Protocol p) 00073 { 00074 if (socket < 0) { 00075 return false; 00076 } 00077 sreg<uint8_t>(socket, Sn_MR, p); 00078 return true; 00079 } 00080 00081 bool WIZ820io::connect(int socket, const char * host, int port, int timeout_ms) 00082 { 00083 if (socket < 0) { 00084 return false; 00085 } 00086 sreg<uint8_t>(socket, Sn_MR, TCP); 00087 scmd(socket, OPEN); 00088 sreg_ip(socket, Sn_DIPR, host); 00089 sreg<uint16_t>(socket, Sn_DPORT, port); 00090 sreg<uint16_t>(socket, Sn_PORT, new_port()); 00091 scmd(socket, CONNECT); 00092 Timer t; 00093 t.reset(); 00094 t.start(); 00095 while(!is_connected(socket)) { 00096 if (t.read_ms() > timeout_ms) { 00097 return false; 00098 } 00099 } 00100 return true; 00101 } 00102 00103 bool WIZ820io::gethostbyname(const char* host, uint32_t* ip) 00104 { 00105 uint32_t addr = str_to_ip(host); 00106 char buf[17]; 00107 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff); 00108 if (strcmp(buf, host) == 0) { 00109 *ip = addr; 00110 return true; 00111 } 00112 DNSClient client; 00113 if(client.lookup(host)) { 00114 *ip = client.ip; 00115 return true; 00116 } 00117 return false; 00118 } 00119 00120 bool WIZ820io::disconnect() 00121 { 00122 return true; 00123 } 00124 00125 bool WIZ820io::is_connected(int socket) 00126 { 00127 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00128 return true; 00129 } 00130 return false; 00131 } 00132 00133 void WIZ820io::reset() 00134 { 00135 reset_pin = 1; 00136 reset_pin = 0; 00137 wait_us(2); // 2us 00138 reset_pin = 1; 00139 wait_ms(150); // 150ms 00140 reg_wr<uint8_t>(MR, 1<<7); 00141 #ifdef TARGET_LPC1114 00142 uint8_t mac[6] = {0x00,0x02,0xf7,0xf0,0x00,0x00}; 00143 #else 00144 uint8_t mac[6]; 00145 mbed_mac_address((char*)mac); 00146 #endif 00147 reg_wr_mac(SHAR, mac); 00148 } 00149 00150 bool WIZ820io::close(int socket) 00151 { 00152 if (socket < 0) { 00153 return false; 00154 } 00155 // if not connected, return 00156 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00157 return true; 00158 } 00159 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00160 scmd(socket, DISCON); 00161 } 00162 scmd(socket, CLOSE); 00163 return true; 00164 } 00165 00166 int WIZ820io::wait_readable(int socket, int wait_time_ms, int req_size) 00167 { 00168 if (socket < 0) { 00169 return -1; 00170 } 00171 Timer t; 00172 t.reset(); 00173 t.start(); 00174 while(1) { 00175 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00176 if (size > req_size) { 00177 return size; 00178 } 00179 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00180 break; 00181 } 00182 } 00183 return -1; 00184 } 00185 00186 int WIZ820io::wait_writeable(int socket, int wait_time_ms, int req_size) 00187 { 00188 if (socket < 0) { 00189 return -1; 00190 } 00191 Timer t; 00192 t.reset(); 00193 t.start(); 00194 while(1) { 00195 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00196 if (size > req_size) { 00197 return size; 00198 } 00199 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00200 break; 00201 } 00202 } 00203 return -1; 00204 } 00205 00206 int WIZ820io::send(int socket, const char * str, int len) 00207 { 00208 if (socket < 0) { 00209 return -1; 00210 } 00211 uint16_t base = 0x8000 + socket * 0x800; 00212 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00213 uint16_t dst = base + (ptr&(0x800-1)); 00214 if ((dst + len) > (base+0x800)) { 00215 int len2 = base + 0x800 - dst; 00216 spi_write(dst, (uint8_t*)str, len2); 00217 spi_write(base, (uint8_t*)str+len2, len-len2); 00218 } else { 00219 spi_write(dst, (uint8_t*)str, len); 00220 } 00221 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00222 scmd(socket, SEND); 00223 return len; 00224 } 00225 00226 int WIZ820io::recv(int socket, char* buf, int len) 00227 { 00228 if (socket < 0) { 00229 return -1; 00230 } 00231 uint16_t base = 0xc000 + socket * 0x800; 00232 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00233 uint16_t src = base + (ptr&(0x800-1)); 00234 if ((src + len) > (base+0x800)) { 00235 int len2 = base + 0x800 - src; 00236 spi_read(src, (uint8_t*)buf, len2); 00237 spi_read(base, (uint8_t*)buf+len2, len-len2); 00238 } else { 00239 spi_read(src, (uint8_t*)buf, len); 00240 } 00241 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00242 scmd(socket, RECV); 00243 return len; 00244 } 00245 00246 int WIZ820io::new_socket() 00247 { 00248 for(int s = 0; s < 8; s++) { 00249 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00250 return s; 00251 } 00252 } 00253 return -1; 00254 } 00255 00256 uint16_t WIZ820io::new_port() 00257 { 00258 uint16_t port = rand(); 00259 port |= 49152; 00260 return port; 00261 } 00262 00263 void WIZ820io::scmd(int socket, Command cmd) 00264 { 00265 sreg<uint8_t>(socket, Sn_CR, cmd); 00266 while(sreg<uint8_t>(socket, Sn_CR)) 00267 ; 00268 } 00269 00270 void WIZ820io::spi_write(uint16_t addr, const uint8_t *buf, uint16_t len) 00271 { 00272 cs = 0; 00273 spi->write(addr >> 8); 00274 spi->write(addr & 0xff); 00275 spi->write((0x80 | ((len & 0x7f00) >> 8))); 00276 spi->write(len & 0xff); 00277 for(int i = 0; i < len; i++) { 00278 spi->write(buf[i]); 00279 } 00280 cs = 1; 00281 00282 #if DBG_SPI 00283 debug("[SPI]W %04x(%d)", addr, len); 00284 for(int i = 0; i < len; i++) { 00285 debug(" %02x", buf[i]); 00286 if (i > 16) { 00287 debug(" ..."); 00288 break; 00289 } 00290 } 00291 debug("\r\n"); 00292 #endif 00293 } 00294 00295 void WIZ820io::spi_read(uint16_t addr, uint8_t *buf, uint16_t len) 00296 { 00297 cs = 0; 00298 spi->write(addr >> 8); 00299 spi->write(addr & 0xff); 00300 spi->write((0x00 | ((len & 0x7f00) >> 8))); 00301 spi->write(len & 0xff); 00302 for(int i = 0; i < len; i++) { 00303 buf[i] = spi->write(0); 00304 } 00305 cs = 1; 00306 00307 #if DBG_SPI 00308 debug("[SPI]R %04x(%d)", addr, len); 00309 for(int i = 0; i < len; i++) { 00310 debug(" %02x", buf[i]); 00311 if (i > 16) { 00312 debug(" ..."); 00313 break; 00314 } 00315 } 00316 debug("\r\n"); 00317 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) { 00318 wait_ms(200); 00319 } 00320 #endif 00321 } 00322 00323 uint32_t str_to_ip(const char* str) 00324 { 00325 uint32_t ip = 0; 00326 char* p = (char*)str; 00327 for(int i = 0; i < 4; i++) { 00328 ip |= atoi(p); 00329 p = strchr(p, '.'); 00330 if (p == NULL) { 00331 break; 00332 } 00333 ip <<= 8; 00334 p++; 00335 } 00336 return ip; 00337 } 00338 00339 void printfBytes(char* str, uint8_t* buf, int len) 00340 { 00341 printf("%s %d:", str, len); 00342 for(int i = 0; i < len; i++) { 00343 printf(" %02x", buf[i]); 00344 } 00345 printf("\n"); 00346 } 00347 00348 void printHex(uint8_t* buf, int len) 00349 { 00350 for(int i = 0; i < len; i++) { 00351 if ((i%16) == 0) { 00352 printf("%p", buf+i); 00353 } 00354 printf(" %02x", buf[i]); 00355 if ((i%16) == 15) { 00356 printf("\n"); 00357 } 00358 } 00359 printf("\n"); 00360 } 00361 00362 void debug_hex(uint8_t* buf, int len) 00363 { 00364 for(int i = 0; i < len; i++) { 00365 if ((i%16) == 0) { 00366 debug("%p", buf+i); 00367 } 00368 debug(" %02x", buf[i]); 00369 if ((i%16) == 15) { 00370 debug("\n"); 00371 } 00372 } 00373 debug("\n"); 00374 }
Generated on Thu Jul 14 2022 11:02:04 by 1.7.2