Update of W5500 Interface for mbed-os
Embed:
(wiki syntax)
Show/hide line numbers
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 0 00038 #define w5500_ACCEPT_TIMEOUT 3000 00039 00040 /* Interface implementation */ 00041 00042 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) : 00043 WIZnet_Chip(mosi, miso, sclk, cs, reset) 00044 { 00045 ip_set = false; 00046 init(); 00047 } 00048 00049 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) : 00050 WIZnet_Chip(spi, cs, reset) 00051 { 00052 ip_set = false; 00053 init(); 00054 } 00055 00056 w5500_socket* W5500Interface::get_sock(int fd) 00057 { 00058 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00059 if (w5500_sockets[i].fd == -1) { 00060 w5500_sockets[i].fd = fd; 00061 w5500_sockets[i].proto = NSAPI_TCP; 00062 w5500_sockets[i].connected = false; 00063 w5500_sockets[i].callback = NULL; 00064 w5500_sockets[i].callback_data = NULL; 00065 return &w5500_sockets[i]; 00066 } 00067 } 00068 return NULL; 00069 } 00070 00071 void W5500Interface::init_socks() 00072 { 00073 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00074 w5500_sockets[i].fd = -1; 00075 w5500_sockets[i].proto = NSAPI_TCP; 00076 w5500_sockets[i].callback = NULL; 00077 w5500_sockets[i].callback_data = NULL; 00078 w5500_sockets[i].connected = false; 00079 } 00080 00081 //initialize the socket isr 00082 _daemon = new Thread(osPriorityNormal, 1024); 00083 _daemon->start(callback(this, &W5500Interface::daemon)); 00084 } 00085 00086 int W5500Interface::init() 00087 { 00088 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0" 00089 //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); // 00090 reset(); 00091 init_socks(); 00092 return 0; 00093 } 00094 00095 int W5500Interface::init(uint8_t * mac) 00096 { 00097 // 00098 for (int i =0; i < 6; i++) this->mac[i] = mac[i]; 00099 // 00100 reset(); 00101 setmac(); 00102 init_socks(); 00103 return 0; 00104 } 00105 00106 // add this function, because sometimes no needed MAC address in init calling. 00107 int W5500Interface::init(const char* ip, const char* mask, const char* gateway) 00108 { 00109 this->ip = str_to_ip(ip); 00110 strcpy(ip_string, ip); 00111 ip_set = true; 00112 this->netmask = str_to_ip(mask); 00113 this->gateway = str_to_ip(gateway); 00114 reset(); 00115 00116 // @Jul. 8. 2014 add code. should be called to write chip. 00117 setip(); 00118 init_socks(); 00119 00120 return 0; 00121 } 00122 00123 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway) 00124 { 00125 // 00126 for (int i =0; i < 6; i++) this->mac[i] = mac[i]; 00127 // 00128 this->ip = str_to_ip(ip); 00129 strcpy(ip_string, ip); 00130 ip_set = true; 00131 this->netmask = str_to_ip(mask); 00132 this->gateway = str_to_ip(gateway); 00133 reset(); 00134 00135 // @Jul. 8. 2014 add code. should be called to write chip. 00136 setmac(); 00137 setip(); 00138 init_socks(); 00139 00140 return 0; 00141 } 00142 00143 void W5500Interface::daemon () { 00144 for (;;) { 00145 for (int i=0; i<MAX_SOCK_NUM ; i++) { 00146 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) { 00147 int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR); 00148 if (size > 0) { 00149 led1 = !led1; 00150 w5500_sockets[i].callback(w5500_sockets[i].callback_data); 00151 } 00152 } 00153 } 00154 wait(0.2); 00155 } 00156 } 00157 00158 int W5500Interface::connect() 00159 { 00160 if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE; 00161 return 0; 00162 } 00163 00164 int W5500Interface::disconnect() 00165 { 00166 WIZnet_Chip::disconnect(); 00167 return 0; 00168 } 00169 00170 const char *W5500Interface::get_ip_address() 00171 { 00172 uint32_t ip = reg_rd<uint32_t>(SIPR); 00173 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff); 00174 return ip_string; 00175 } 00176 00177 const char *W5500Interface::get_mac_address() 00178 { 00179 uint8_t mac[6]; 00180 reg_rd_mac(SHAR, mac); 00181 snprintf(mac_string, sizeof(mac_string), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00182 return mac_string; 00183 } 00184 00185 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) 00186 { 00187 //a socket is created the same way regardless of the protocol 00188 int sock_fd = WIZnet_Chip::new_socket(); 00189 if (sock_fd < 0) { 00190 return NSAPI_ERROR_NO_SOCKET; 00191 } 00192 00193 w5500_socket *h = get_sock(sock_fd); 00194 00195 if (!h) { 00196 return NSAPI_ERROR_NO_SOCKET; 00197 } 00198 00199 h->proto = proto; 00200 h->connected = false; 00201 h->callback = NULL; 00202 h->callback_data = NULL; 00203 00204 //new up an int to store the socket fd 00205 *handle = h; 00206 00207 return 0; 00208 } 00209 00210 void W5500Interface::signal_event(nsapi_socket_t handle) 00211 { 00212 if (SKT(handle)->callback != NULL) { 00213 SKT(handle)->callback(SKT(handle)->callback_data); 00214 } 00215 } 00216 00217 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle) 00218 { 00219 if (handle == NULL) return 0; 00220 WIZnet_Chip::close(SKT(handle)->fd); 00221 00222 SKT(handle)->fd = -1; 00223 00224 return 0; 00225 } 00226 00227 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address) 00228 { 00229 if (handle < 0) { 00230 return NSAPI_ERROR_DEVICE_ERROR; 00231 } 00232 00233 switch (SKT(handle)->proto) { 00234 case NSAPI_UDP: 00235 // set local port 00236 if (address.get_port() != 0) { 00237 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port()); 00238 } else { 00239 udp_local_port++; 00240 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, udp_local_port); 00241 } 00242 // set udp protocol 00243 WIZnet_Chip::setProtocol(SKT(handle)->fd, UDP); 00244 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN); 00245 return 0; 00246 case NSAPI_TCP: 00247 listen_port = address.get_port(); 00248 // set TCP protocol 00249 WIZnet_Chip::setProtocol(SKT(handle)->fd, TCP); 00250 // set local port 00251 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port()); 00252 // connect the network 00253 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN); 00254 return 0; 00255 } 00256 00257 return NSAPI_ERROR_DEVICE_ERROR; 00258 } 00259 00260 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog) 00261 { 00262 if (SKT(handle)->fd < 0) { 00263 return NSAPI_ERROR_NO_SOCKET; 00264 } 00265 if (backlog != 1) { 00266 return NSAPI_ERROR_NO_SOCKET; 00267 } 00268 WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN); 00269 return 0; 00270 } 00271 00272 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address) 00273 { 00274 //check for a valid socket 00275 if (SKT(handle)->fd < 0) { 00276 return NSAPI_ERROR_NO_SOCKET; 00277 } 00278 00279 //before we attempt to connect, we are not connected 00280 SKT(handle)->connected = false; 00281 00282 //try to connect 00283 if (!WIZnet_Chip::connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) { 00284 return -1; 00285 } 00286 00287 //we are now connected 00288 SKT(handle)->connected = true; 00289 00290 return 0; 00291 } 00292 00293 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) 00294 { 00295 if (SKT(server)->fd < 0) { 00296 return NSAPI_ERROR_NO_SOCKET; 00297 } 00298 00299 SKT(server)->connected = false; 00300 00301 Timer t; 00302 t.reset(); 00303 t.start(); 00304 00305 while(1) { 00306 //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) { 00307 // printf("W5500Interface::socket_accept, timed out\r\n"); 00308 // return NSAPI_ERROR_WOULD_BLOCK; 00309 //} 00310 00311 nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR); 00312 00313 if (err == SOCK_ESTABLISHED) { 00314 break; 00315 } 00316 } 00317 00318 //get socket for the connection 00319 *handle = get_sock(SKT(server)->fd); 00320 00321 if (!(*handle)) { 00322 error("No more socketa for binding"); 00323 return NSAPI_ERROR_NO_SOCKET; 00324 } 00325 00326 //give it all of the socket info from the server 00327 SKT(*handle)->proto = SKT(server)->proto; 00328 SKT(*handle)->connected = true; 00329 00330 //create a new tcp socket for the server 00331 SKT(server)->fd = WIZnet_Chip::new_socket(); 00332 if (SKT(server)->fd < 0) { 00333 error("Unable to open a new socket"); 00334 return NSAPI_ERROR_NO_SOCKET; 00335 } 00336 00337 SKT(server)->proto = NSAPI_TCP; 00338 SKT(server)->connected = false; 00339 00340 SocketAddress _addr; 00341 _addr.set_port(listen_port); 00342 00343 // and then, for the next connection, server socket should be assigned new one. 00344 if (socket_bind(server, _addr) < 0) { 00345 error("No more socketa for binding"); 00346 return NSAPI_ERROR_NO_SOCKET; 00347 } 00348 00349 if (socket_listen(server, 1) < 0) { 00350 error("No more sockets for listening"); 00351 } 00352 00353 if (address) { 00354 uint32_t ip = WIZnet_Chip::sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR); 00355 char host[17]; 00356 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff); 00357 int port = WIZnet_Chip::sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT); 00358 00359 _addr.set_ip_address(host); 00360 _addr.set_port(port); 00361 *address = _addr; 00362 } 00363 00364 return 0; 00365 } 00366 00367 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size) 00368 { 00369 int writtenLen = 0; 00370 while (writtenLen < size) { 00371 int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); 00372 if (_size < 0) { 00373 return NSAPI_ERROR_WOULD_BLOCK; 00374 } 00375 if (_size > (size-writtenLen)) { 00376 _size = (size-writtenLen); 00377 } 00378 int ret = WIZnet_Chip::send(SKT(handle)->fd, (char*)data, (int)_size); 00379 if (ret < 0) { 00380 return -1; 00381 } 00382 writtenLen += ret; 00383 } 00384 return writtenLen; 00385 } 00386 00387 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size) 00388 { 00389 // add to cover exception. 00390 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) { 00391 return -1; 00392 } 00393 00394 int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); 00395 00396 if (_size < 0) { 00397 return NSAPI_ERROR_WOULD_BLOCK; 00398 } 00399 00400 if (_size > size) { 00401 _size = size; 00402 } 00403 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)data, (int)_size); 00404 } 00405 00406 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address, 00407 const void *data, nsapi_size_t size) 00408 { 00409 int len = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1); 00410 if (len < 0) { 00411 return NSAPI_ERROR_WOULD_BLOCK;; 00412 } 00413 00414 // set remote host 00415 WIZnet_Chip::sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address()); 00416 // set remote port 00417 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port()); 00418 00419 return WIZnet_Chip::send(SKT(handle)->fd, (const char*)data, size); 00420 } 00421 00422 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, 00423 void *buffer, nsapi_size_t size) 00424 { 00425 //check for null pointers 00426 if (address == NULL || buffer == NULL) return -1; 00427 00428 uint8_t info[8]; 00429 int len = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info)); 00430 if (len < 0) { 00431 return NSAPI_ERROR_WOULD_BLOCK; 00432 } 00433 00434 //receive endpoint information 00435 WIZnet_Chip::recv(SKT(handle)->fd, (char*)info, sizeof(info)); 00436 00437 char addr[17]; 00438 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]); 00439 uint16_t port = info[4]<<8|info[5]; 00440 address->set_ip_address(addr); 00441 address->set_port(port); 00442 00443 int udp_size = info[6]<<8|info[7]; 00444 00445 if (udp_size > (len-sizeof(info))) { 00446 return -1; 00447 } 00448 00449 //receive from socket 00450 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)buffer, udp_size); 00451 } 00452 00453 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data) 00454 { 00455 if (handle == NULL) return; 00456 00457 SKT(handle)->callback = callback; 00458 SKT(handle)->callback_data = data; 00459 }
Generated on Wed Jul 13 2022 00:54:44 by 1.7.2