W5500 from SeeedStudio on NUCLEO-L476RG
Dependents: coap-example Borsch coap-example
Fork of W5500Interface by
W5500Interface.cpp
00001 // EthernetInterface for W5500 2014/8/20 00002 /* 00003 // sample usgae. 00004 // copy below code block to main code. 00005 00006 #if defined(TARGET_LPC1114) 00007 SPI spi(dp2, dp1, dp6); // mosi, miso, sclk 00008 EthernetInterface eth(&spi, dp25, dp26); // spi, cs, reset 00009 wait(1); // 1 second for stable state 00010 #elif defined(TARGET_LPC1768) 00011 SPI spi(p11, p12, p13); // mosi, miso, sclk 00012 EthernetInterface eth(&spi, p14, p15); // spi, cs, reset 00013 wait(1); // 1 second for stable state 00014 #elif defined(TARGET_LPC11U68) 00015 SPI spi(P0_9, P0_8, P1_29); // mosi, miso, sclk 00016 EthernetInterface eth(&spi, P0_2, P1_28);//, nRESET(p9); // reset pin is dummy, don't affect any pin of WIZ550io 00017 spi.format(8,0); // 8bit, mode 0 00018 spi.frequency(7000000); // 7MHz 00019 wait(1); // 1 second for stable state 00020 #endif 00021 00022 eth.init(); //Use DHCP 00023 dbg.printf("init\r\n"); 00024 eth.connect(); 00025 dbg.printf("IP address: %s\r\n", eth.getIPAddress()); 00026 00027 */ 00028 00029 #include "mbed.h" 00030 #include "W5500Interface.h" 00031 00032 static int udp_local_port = 0; 00033 00034 DigitalOut led1(LED1); 00035 00036 #define SKT(h) ((w5500_socket*)h) 00037 #define w5500_WAIT_TIMEOUT 1500 00038 #define w5500_ACCEPT_TIMEOUT 3000 00039 00040 #define w5500_INTF_DBG 0 00041 00042 #if w5500_INTF_DBG 00043 #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0); 00044 #else 00045 #define DBG(...) while(0); 00046 #endif 00047 00048 00049 /* Interface implementation */ 00050 00051 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) : 00052 WIZnet_Chip(mosi, miso, sclk, cs, reset) 00053 { 00054 ip_set = false; 00055 } 00056 00057 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) : 00058 WIZnet_Chip(spi, cs, reset) 00059 { 00060 ip_set = false; 00061 } 00062 00063 w5500_socket* W5500Interface::get_sock(int fd) 00064 { 00065 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00066 if (w5500_sockets[i].fd == -1) { 00067 w5500_sockets[i].fd = fd; 00068 w5500_sockets[i].proto = NSAPI_TCP; 00069 w5500_sockets[i].connected = false; 00070 w5500_sockets[i].callback = NULL; 00071 w5500_sockets[i].callback_data = NULL; 00072 return &w5500_sockets[i]; 00073 } 00074 } 00075 return NULL; 00076 } 00077 00078 void W5500Interface::init_socks() 00079 { 00080 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00081 w5500_sockets[i].fd = -1; 00082 w5500_sockets[i].proto = NSAPI_TCP; 00083 w5500_sockets[i].callback = NULL; 00084 w5500_sockets[i].callback_data = NULL; 00085 w5500_sockets[i].connected = false; 00086 } 00087 00088 //initialize the socket isr 00089 _daemon = new Thread(osPriorityNormal, 1024); 00090 _daemon->start(callback(this, &W5500Interface::daemon)); 00091 } 00092 00093 int W5500Interface::init() 00094 { 00095 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0" 00096 //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); // 00097 reset(); 00098 init_socks(); 00099 return 0; 00100 } 00101 00102 int W5500Interface::init(uint8_t * mac) 00103 { 00104 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0" 00105 for (int i =0; i < 6; i++) this->mac[i] = mac[i]; 00106 setmac(); 00107 reset(); // sets buffers; does not alter MAC 00108 init_socks(); 00109 return 0; 00110 } 00111 00112 // add this function, because sometimes no needed MAC address in init calling. 00113 int W5500Interface::init(const char* ip, const char* mask, const char* gateway) 00114 { 00115 this->ip = str_to_ip(ip); 00116 strcpy(ip_string, ip); 00117 ip_set = true; 00118 this->netmask = str_to_ip(mask); 00119 this->gateway = str_to_ip(gateway); 00120 reset(); 00121 00122 // @Jul. 8. 2014 add code. should be called to write chip. 00123 setip(); 00124 init_socks(); 00125 00126 return 0; 00127 } 00128 00129 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway) 00130 { 00131 // 00132 for (int i =0; i < 6; i++) this->mac[i] = mac[i]; 00133 // 00134 this->ip = str_to_ip(ip); 00135 strcpy(ip_string, ip); 00136 ip_set = true; 00137 this->netmask = str_to_ip(mask); 00138 this->gateway = str_to_ip(gateway); 00139 reset(); 00140 00141 // @Jul. 8. 2014 add code. should be called to write chip. 00142 setmac(); 00143 setip(); 00144 init_socks(); 00145 00146 return 0; 00147 } 00148 00149 void W5500Interface::daemon () { 00150 for (;;) { 00151 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00152 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) { 00153 int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR); 00154 if (size > 0) { 00155 led1 = !led1; 00156 w5500_sockets[i].callback(w5500_sockets[i].callback_data); 00157 } 00158 } 00159 } 00160 wait(0.2); 00161 } 00162 } 00163 00164 int W5500Interface::connect() 00165 { 00166 if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE; 00167 return 0; 00168 } 00169 00170 int W5500Interface::disconnect() 00171 { 00172 WIZnet_Chip::disconnect(); 00173 return 0; 00174 } 00175 00176 const char *W5500Interface::get_ip_address() 00177 { 00178 uint32_t ip = reg_rd<uint32_t>(SIPR); 00179 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff); 00180 return ip_string; 00181 } 00182 00183 const char *W5500Interface::get_mac_address() 00184 { 00185 uint8_t mac[6]; 00186 reg_rd_mac(SHAR, mac); 00187 snprintf(mac_string, sizeof(mac_string), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00188 return mac_string; 00189 } 00190 00191 void W5500Interface::get_mac(uint8_t mac[6]) 00192 { 00193 reg_rd_mac(SHAR, mac); 00194 } 00195 00196 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) 00197 { 00198 //a socket is created the same way regardless of the protocol 00199 int sock_fd = WIZnet_Chip::new_socket(); 00200 if (sock_fd < 0) { 00201 return NSAPI_ERROR_NO_SOCKET; 00202 } 00203 00204 w5500_socket *h = get_sock(sock_fd); 00205 00206 if (!h) { 00207 return NSAPI_ERROR_NO_SOCKET; 00208 } 00209 00210 h->proto = proto; 00211 h->connected = false; 00212 h->callback = NULL; 00213 h->callback_data = NULL; 00214 00215 //new up an int to store the socket fd 00216 *handle = h; 00217 DBG("fd: %d\n", sock_fd); 00218 return 0; 00219 } 00220 00221 void W5500Interface::signal_event(nsapi_socket_t handle) 00222 { 00223 DBG("fd: %d\n", SKT(handle)->fd); 00224 if (SKT(handle)->callback != NULL) { 00225 SKT(handle)->callback(SKT(handle)->callback_data); 00226 } 00227 } 00228 00229 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle) 00230 { 00231 if (handle == NULL) return 0; 00232 DBG("fd: %d\n", SKT(handle)->fd); 00233 WIZnet_Chip::close(SKT(handle)->fd); 00234 00235 SKT(handle)->fd = -1; 00236 00237 return 0; 00238 } 00239 00240 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address) 00241 { 00242 if (handle < 0) { 00243 return NSAPI_ERROR_DEVICE_ERROR; 00244 } 00245 DBG("fd: %d, port: %d\n", SKT(handle)->fd, address.get_port()); 00246 00247 switch (SKT(handle)->proto) { 00248 case NSAPI_UDP: 00249 // set local port 00250 if (address.get_port() != 0) { 00251 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port()); 00252 } else { 00253 udp_local_port++; 00254 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, udp_local_port); 00255 } 00256 // set udp protocol 00257 WIZnet_Chip::setProtocol(SKT(handle)->fd, UDP); 00258 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN); 00259 return 0; 00260 case NSAPI_TCP: 00261 listen_port = address.get_port(); 00262 // set TCP protocol 00263 WIZnet_Chip::setProtocol(SKT(handle)->fd, TCP); 00264 // set local port 00265 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port()); 00266 // connect the network 00267 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN); 00268 return 0; 00269 } 00270 00271 return NSAPI_ERROR_DEVICE_ERROR; 00272 } 00273 00274 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog) 00275 { 00276 DBG("fd: %d\n", SKT(handle)->fd); 00277 if (SKT(handle)->fd < 0) { 00278 return NSAPI_ERROR_NO_SOCKET; 00279 } 00280 if (backlog != 1) { 00281 return NSAPI_ERROR_NO_SOCKET; 00282 } 00283 WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN); 00284 return 0; 00285 } 00286 00287 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address) 00288 { 00289 DBG("fd: %d\n", SKT(handle)->fd); 00290 //check for a valid socket 00291 if (SKT(handle)->fd < 0) { 00292 return NSAPI_ERROR_NO_SOCKET; 00293 } 00294 00295 //before we attempt to connect, we are not connected 00296 SKT(handle)->connected = false; 00297 00298 //try to connect 00299 if (!WIZnet_Chip::connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) { 00300 return -1; 00301 } 00302 00303 //we are now connected 00304 SKT(handle)->connected = true; 00305 00306 return 0; 00307 } 00308 00309 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) 00310 { 00311 DBG("fd: %d\n", SKT(handle)->fd); 00312 if (SKT(server)->fd < 0) { 00313 return NSAPI_ERROR_NO_SOCKET; 00314 } 00315 00316 SKT(server)->connected = false; 00317 00318 Timer t; 00319 t.reset(); 00320 t.start(); 00321 00322 while(1) { 00323 //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) { 00324 // printf("W5500Interface::socket_accept, timed out\r\n"); 00325 // return NSAPI_ERROR_WOULD_BLOCK; 00326 //} 00327 00328 nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR); 00329 00330 if (err == SOCK_ESTABLISHED) { 00331 break; 00332 } 00333 } 00334 00335 //get socket for the connection 00336 *handle = get_sock(SKT(server)->fd); 00337 00338 if (!(*handle)) { 00339 error("No more sockets for binding"); 00340 return NSAPI_ERROR_NO_SOCKET; 00341 } 00342 00343 //give it all of the socket info from the server 00344 SKT(*handle)->proto = SKT(server)->proto; 00345 SKT(*handle)->connected = true; 00346 00347 //create a new tcp socket for the server 00348 SKT(server)->fd = WIZnet_Chip::new_socket(); 00349 if (SKT(server)->fd < 0) { 00350 error("Unable to open a new socket"); 00351 return NSAPI_ERROR_NO_SOCKET; 00352 } 00353 00354 SKT(server)->proto = NSAPI_TCP; 00355 SKT(server)->connected = false; 00356 00357 SocketAddress _addr; 00358 _addr.set_port(listen_port); 00359 00360 // and then, for the next connection, server socket should be assigned new one. 00361 if (socket_bind(server, _addr) < 0) { 00362 error("No more sockets for binding"); 00363 return NSAPI_ERROR_NO_SOCKET; 00364 } 00365 00366 if (socket_listen(server, 1) < 0) { 00367 error("No more sockets for listening"); 00368 } 00369 00370 if (address) { 00371 uint32_t ip = WIZnet_Chip::sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR); 00372 char host[17]; 00373 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff); 00374 int port = WIZnet_Chip::sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT); 00375 00376 _addr.set_ip_address(host); 00377 _addr.set_port(port); 00378 *address = _addr; 00379 } 00380 00381 return 0; 00382 } 00383 00384 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size) 00385 { 00386 DBG("fd: %d\n", SKT(handle)->fd); 00387 int writtenLen = 0; 00388 while (writtenLen < size) { 00389 int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); 00390 if (_size < 0) { 00391 return NSAPI_ERROR_WOULD_BLOCK; 00392 } 00393 if (_size > (size-writtenLen)) { 00394 _size = (size-writtenLen); 00395 } 00396 int ret = WIZnet_Chip::send(SKT(handle)->fd, (char*)data, (int)_size); 00397 if (ret < 0) { 00398 DBG("returning error -1\n"); 00399 return -1; 00400 } 00401 writtenLen += ret; 00402 } 00403 return writtenLen; 00404 } 00405 00406 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size) 00407 { 00408 DBG("fd: %d\n", SKT(handle)->fd); 00409 // add to cover exception. 00410 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) { 00411 return -1; 00412 } 00413 00414 int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); 00415 00416 if (_size < 0) { 00417 return NSAPI_ERROR_WOULD_BLOCK; 00418 } 00419 00420 if (_size > size) { 00421 _size = size; 00422 } 00423 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)data, (int)_size); 00424 } 00425 00426 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address, 00427 const void *data, nsapi_size_t size) 00428 { 00429 DBG("fd: %d, ip: %s:%d\n", SKT(handle)->fd, address.get_ip_address(), address.get_port()); 00430 if (WIZnet_Chip::is_closed(SKT(handle)->fd)) { 00431 nsapi_error_t err = socket_bind(handle, address); 00432 if (err < 0) { 00433 DBG("failed to bind socket: %d\n", err); 00434 return err; 00435 } 00436 } 00437 //compare with original: int size = eth->wait_writeable(_sock_fd, _blocking ? -1 : _timeout, length-1); 00438 int len = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1); 00439 if (len < 0) { 00440 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n"); 00441 return NSAPI_ERROR_WOULD_BLOCK;; 00442 } 00443 00444 // set remote host 00445 WIZnet_Chip::sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address()); 00446 // set remote port 00447 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port()); 00448 00449 nsapi_size_or_error_t err = WIZnet_Chip::send(SKT(handle)->fd, (const char*)data, size); 00450 DBG("rv: %d, size: %d\n", err, size); 00451 #if w5500_INTF_DBG 00452 if (err > 0) { 00453 debug("[socket_sendto] data: "); 00454 for(int i = 0; i < err; i++) { 00455 if ((i%16) == 0) { 00456 debug("\n"); 00457 } 00458 debug(" %02x", ((uint8_t*)data)[i]); 00459 } 00460 if ((err-1%16) != 0) { 00461 debug("\n"); 00462 } 00463 } 00464 #endif 00465 return err; 00466 } 00467 00468 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, 00469 void *buffer, nsapi_size_t size) 00470 { 00471 DBG("fd: %d\n", SKT(handle)->fd); 00472 //check for null pointers 00473 if (buffer == NULL) { 00474 DBG("buffer is NULL; receive is ABORTED\n"); 00475 return -1; 00476 } 00477 00478 uint8_t info[8]; 00479 int len = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info)); 00480 if (len < 0) { 00481 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n"); 00482 return NSAPI_ERROR_WOULD_BLOCK; 00483 } 00484 00485 //receive endpoint information 00486 WIZnet_Chip::recv(SKT(handle)->fd, (char*)info, sizeof(info)); 00487 00488 char addr[17]; 00489 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]); 00490 uint16_t port = info[4]<<8|info[5]; 00491 // original behavior was to terminate execution if address is NULL 00492 if (address != NULL) { 00493 //DBG("[socket_recvfrom] warn: addressis NULL"); 00494 address->set_ip_address(addr); 00495 address->set_port(port); 00496 } 00497 00498 int udp_size = info[6]<<8|info[7]; 00499 00500 if (udp_size > (len-sizeof(info))) { 00501 DBG("error: udp_size > (len-sizeof(info))\n"); 00502 return -1; 00503 } 00504 00505 //receive from socket 00506 nsapi_size_or_error_t err = WIZnet_Chip::recv(SKT(handle)->fd, (char*)buffer, udp_size); 00507 DBG("rv: %d\n", err); 00508 #if w5500_INTF_DBG 00509 if (err > 0) { 00510 debug("[socket_recvfrom] buffer:"); 00511 for(int i = 0; i < err; i++) { 00512 if ((i%16) == 0) { 00513 debug("\n"); 00514 } 00515 debug(" %02x", ((uint8_t*)buffer)[i]); 00516 } 00517 if ((err-1%16) != 0) { 00518 debug("\n"); 00519 } 00520 } 00521 #endif 00522 return err; 00523 } 00524 00525 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data) 00526 { 00527 if (handle == NULL) return; 00528 DBG("fd: %d, callback: %p\n", SKT(handle)->fd, callback); 00529 SKT(handle)->callback = callback; 00530 SKT(handle)->callback_data = data; 00531 }
Generated on Fri Jul 15 2022 13:32:25 by 1.7.2