W5500 from SeeedStudio on NUCLEO-L476RG

Dependents:   coap-example Borsch coap-example

Fork of W5500Interface by AMETEK Powervar

Committer:
sgnezdov
Date:
Thu Jul 06 05:46:17 2017 +0000
Revision:
5:41393623ead4
Parent:
4:80e302a610fd
fined tuned debugging; turned off debugging

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgriffin65 0:77e050d1fb12 1 // EthernetInterface for W5500 2014/8/20
dgriffin65 0:77e050d1fb12 2 /*
dgriffin65 0:77e050d1fb12 3 // sample usgae.
dgriffin65 0:77e050d1fb12 4 // copy below code block to main code.
dgriffin65 0:77e050d1fb12 5
dgriffin65 0:77e050d1fb12 6 #if defined(TARGET_LPC1114)
dgriffin65 0:77e050d1fb12 7 SPI spi(dp2, dp1, dp6); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 8 EthernetInterface eth(&spi, dp25, dp26); // spi, cs, reset
dgriffin65 0:77e050d1fb12 9 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 10 #elif defined(TARGET_LPC1768)
dgriffin65 0:77e050d1fb12 11 SPI spi(p11, p12, p13); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 12 EthernetInterface eth(&spi, p14, p15); // spi, cs, reset
dgriffin65 0:77e050d1fb12 13 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 14 #elif defined(TARGET_LPC11U68)
dgriffin65 0:77e050d1fb12 15 SPI spi(P0_9, P0_8, P1_29); // mosi, miso, sclk
dgriffin65 0:77e050d1fb12 16 EthernetInterface eth(&spi, P0_2, P1_28);//, nRESET(p9); // reset pin is dummy, don't affect any pin of WIZ550io
dgriffin65 0:77e050d1fb12 17 spi.format(8,0); // 8bit, mode 0
dgriffin65 0:77e050d1fb12 18 spi.frequency(7000000); // 7MHz
dgriffin65 0:77e050d1fb12 19 wait(1); // 1 second for stable state
dgriffin65 0:77e050d1fb12 20 #endif
dgriffin65 0:77e050d1fb12 21
dgriffin65 0:77e050d1fb12 22 eth.init(); //Use DHCP
dgriffin65 0:77e050d1fb12 23 dbg.printf("init\r\n");
dgriffin65 0:77e050d1fb12 24 eth.connect();
dgriffin65 0:77e050d1fb12 25 dbg.printf("IP address: %s\r\n", eth.getIPAddress());
dgriffin65 0:77e050d1fb12 26
dgriffin65 0:77e050d1fb12 27 */
dgriffin65 0:77e050d1fb12 28
dgriffin65 0:77e050d1fb12 29 #include "mbed.h"
dgriffin65 0:77e050d1fb12 30 #include "W5500Interface.h"
dgriffin65 0:77e050d1fb12 31
dgriffin65 0:77e050d1fb12 32 static int udp_local_port = 0;
dgriffin65 0:77e050d1fb12 33
dgriffin65 1:2dee44ea52a9 34 DigitalOut led1(LED1);
dgriffin65 1:2dee44ea52a9 35
dgriffin65 0:77e050d1fb12 36 #define SKT(h) ((w5500_socket*)h)
sgnezdov 5:41393623ead4 37 #define w5500_WAIT_TIMEOUT 1500
dgriffin65 0:77e050d1fb12 38 #define w5500_ACCEPT_TIMEOUT 3000
sgnezdov 5:41393623ead4 39
sgnezdov 5:41393623ead4 40 #define w5500_INTF_DBG 0
sgnezdov 5:41393623ead4 41
sgnezdov 5:41393623ead4 42 #if w5500_INTF_DBG
sgnezdov 5:41393623ead4 43 #define DBG(...) do{debug("[%s:%d]", __PRETTY_FUNCTION__,__LINE__);debug(__VA_ARGS__);} while(0);
sgnezdov 5:41393623ead4 44 #else
sgnezdov 5:41393623ead4 45 #define DBG(...) while(0);
sgnezdov 5:41393623ead4 46 #endif
sgnezdov 5:41393623ead4 47
dgriffin65 0:77e050d1fb12 48
dgriffin65 0:77e050d1fb12 49 /* Interface implementation */
dgriffin65 0:77e050d1fb12 50
dgriffin65 0:77e050d1fb12 51 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 52 WIZnet_Chip(mosi, miso, sclk, cs, reset)
dgriffin65 0:77e050d1fb12 53 {
dgriffin65 0:77e050d1fb12 54 ip_set = false;
dgriffin65 0:77e050d1fb12 55 }
dgriffin65 0:77e050d1fb12 56
dgriffin65 0:77e050d1fb12 57 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 58 WIZnet_Chip(spi, cs, reset)
dgriffin65 0:77e050d1fb12 59 {
dgriffin65 0:77e050d1fb12 60 ip_set = false;
dgriffin65 0:77e050d1fb12 61 }
dgriffin65 0:77e050d1fb12 62
dgriffin65 1:2dee44ea52a9 63 w5500_socket* W5500Interface::get_sock(int fd)
dgriffin65 1:2dee44ea52a9 64 {
dgriffin65 1:2dee44ea52a9 65 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 66 if (w5500_sockets[i].fd == -1) {
dgriffin65 1:2dee44ea52a9 67 w5500_sockets[i].fd = fd;
dgriffin65 1:2dee44ea52a9 68 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 69 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 70 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 71 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 72 return &w5500_sockets[i];
dgriffin65 1:2dee44ea52a9 73 }
dgriffin65 1:2dee44ea52a9 74 }
dgriffin65 1:2dee44ea52a9 75 return NULL;
dgriffin65 1:2dee44ea52a9 76 }
dgriffin65 1:2dee44ea52a9 77
dgriffin65 1:2dee44ea52a9 78 void W5500Interface::init_socks()
dgriffin65 1:2dee44ea52a9 79 {
dgriffin65 1:2dee44ea52a9 80 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 81 w5500_sockets[i].fd = -1;
dgriffin65 1:2dee44ea52a9 82 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 83 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 84 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 85 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 86 }
dgriffin65 1:2dee44ea52a9 87
dgriffin65 1:2dee44ea52a9 88 //initialize the socket isr
dgriffin65 1:2dee44ea52a9 89 _daemon = new Thread(osPriorityNormal, 1024);
dgriffin65 1:2dee44ea52a9 90 _daemon->start(callback(this, &W5500Interface::daemon));
dgriffin65 1:2dee44ea52a9 91 }
dgriffin65 1:2dee44ea52a9 92
dgriffin65 0:77e050d1fb12 93 int W5500Interface::init()
dgriffin65 0:77e050d1fb12 94 {
dgriffin65 0:77e050d1fb12 95 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
dgriffin65 1:2dee44ea52a9 96 //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); //
dgriffin65 0:77e050d1fb12 97 reset();
dgriffin65 1:2dee44ea52a9 98 init_socks();
dgriffin65 0:77e050d1fb12 99 return 0;
dgriffin65 0:77e050d1fb12 100 }
dgriffin65 0:77e050d1fb12 101
dgriffin65 0:77e050d1fb12 102 int W5500Interface::init(uint8_t * mac)
dgriffin65 0:77e050d1fb12 103 {
sgnezdov 2:06b6f9f7c071 104 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
dgriffin65 0:77e050d1fb12 105 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 106 setmac();
sgnezdov 2:06b6f9f7c071 107 reset(); // sets buffers; does not alter MAC
dgriffin65 1:2dee44ea52a9 108 init_socks();
dgriffin65 0:77e050d1fb12 109 return 0;
dgriffin65 0:77e050d1fb12 110 }
dgriffin65 0:77e050d1fb12 111
dgriffin65 0:77e050d1fb12 112 // add this function, because sometimes no needed MAC address in init calling.
dgriffin65 0:77e050d1fb12 113 int W5500Interface::init(const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 114 {
dgriffin65 0:77e050d1fb12 115 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 116 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 117 ip_set = true;
dgriffin65 0:77e050d1fb12 118 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 119 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 120 reset();
dgriffin65 0:77e050d1fb12 121
dgriffin65 0:77e050d1fb12 122 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 123 setip();
dgriffin65 1:2dee44ea52a9 124 init_socks();
dgriffin65 0:77e050d1fb12 125
dgriffin65 0:77e050d1fb12 126 return 0;
dgriffin65 0:77e050d1fb12 127 }
dgriffin65 0:77e050d1fb12 128
dgriffin65 0:77e050d1fb12 129 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 130 {
dgriffin65 0:77e050d1fb12 131 //
dgriffin65 0:77e050d1fb12 132 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 133 //
dgriffin65 0:77e050d1fb12 134 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 135 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 136 ip_set = true;
dgriffin65 0:77e050d1fb12 137 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 138 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 139 reset();
dgriffin65 0:77e050d1fb12 140
dgriffin65 0:77e050d1fb12 141 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 142 setmac();
dgriffin65 0:77e050d1fb12 143 setip();
dgriffin65 1:2dee44ea52a9 144 init_socks();
dgriffin65 0:77e050d1fb12 145
dgriffin65 0:77e050d1fb12 146 return 0;
dgriffin65 0:77e050d1fb12 147 }
dgriffin65 0:77e050d1fb12 148
dgriffin65 1:2dee44ea52a9 149 void W5500Interface::daemon () {
dgriffin65 1:2dee44ea52a9 150 for (;;) {
dgriffin65 1:2dee44ea52a9 151 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 152 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) {
dgriffin65 1:2dee44ea52a9 153 int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR);
dgriffin65 1:2dee44ea52a9 154 if (size > 0) {
dgriffin65 1:2dee44ea52a9 155 led1 = !led1;
dgriffin65 1:2dee44ea52a9 156 w5500_sockets[i].callback(w5500_sockets[i].callback_data);
dgriffin65 1:2dee44ea52a9 157 }
dgriffin65 1:2dee44ea52a9 158 }
dgriffin65 1:2dee44ea52a9 159 }
dgriffin65 1:2dee44ea52a9 160 wait(0.2);
dgriffin65 1:2dee44ea52a9 161 }
dgriffin65 1:2dee44ea52a9 162 }
dgriffin65 1:2dee44ea52a9 163
dgriffin65 0:77e050d1fb12 164 int W5500Interface::connect()
dgriffin65 0:77e050d1fb12 165 {
dgriffin65 0:77e050d1fb12 166 if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE;
dgriffin65 0:77e050d1fb12 167 return 0;
dgriffin65 0:77e050d1fb12 168 }
dgriffin65 0:77e050d1fb12 169
dgriffin65 0:77e050d1fb12 170 int W5500Interface::disconnect()
dgriffin65 0:77e050d1fb12 171 {
dgriffin65 0:77e050d1fb12 172 WIZnet_Chip::disconnect();
dgriffin65 0:77e050d1fb12 173 return 0;
dgriffin65 0:77e050d1fb12 174 }
dgriffin65 0:77e050d1fb12 175
dgriffin65 0:77e050d1fb12 176 const char *W5500Interface::get_ip_address()
dgriffin65 0:77e050d1fb12 177 {
dgriffin65 0:77e050d1fb12 178 uint32_t ip = reg_rd<uint32_t>(SIPR);
dgriffin65 0:77e050d1fb12 179 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 180 return ip_string;
dgriffin65 0:77e050d1fb12 181 }
dgriffin65 0:77e050d1fb12 182
dgriffin65 0:77e050d1fb12 183 const char *W5500Interface::get_mac_address()
dgriffin65 0:77e050d1fb12 184 {
dgriffin65 0:77e050d1fb12 185 uint8_t mac[6];
dgriffin65 0:77e050d1fb12 186 reg_rd_mac(SHAR, mac);
dgriffin65 0:77e050d1fb12 187 snprintf(mac_string, sizeof(mac_string), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
dgriffin65 0:77e050d1fb12 188 return mac_string;
dgriffin65 0:77e050d1fb12 189 }
dgriffin65 0:77e050d1fb12 190
sgnezdov 2:06b6f9f7c071 191 void W5500Interface::get_mac(uint8_t mac[6])
sgnezdov 2:06b6f9f7c071 192 {
sgnezdov 2:06b6f9f7c071 193 reg_rd_mac(SHAR, mac);
sgnezdov 2:06b6f9f7c071 194 }
sgnezdov 2:06b6f9f7c071 195
dgriffin65 0:77e050d1fb12 196 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
dgriffin65 0:77e050d1fb12 197 {
dgriffin65 0:77e050d1fb12 198 //a socket is created the same way regardless of the protocol
dgriffin65 0:77e050d1fb12 199 int sock_fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 200 if (sock_fd < 0) {
dgriffin65 0:77e050d1fb12 201 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 202 }
dgriffin65 0:77e050d1fb12 203
dgriffin65 1:2dee44ea52a9 204 w5500_socket *h = get_sock(sock_fd);
dgriffin65 0:77e050d1fb12 205
dgriffin65 1:2dee44ea52a9 206 if (!h) {
dgriffin65 1:2dee44ea52a9 207 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 208 }
dgriffin65 1:2dee44ea52a9 209
dgriffin65 1:2dee44ea52a9 210 h->proto = proto;
dgriffin65 1:2dee44ea52a9 211 h->connected = false;
dgriffin65 1:2dee44ea52a9 212 h->callback = NULL;
dgriffin65 1:2dee44ea52a9 213 h->callback_data = NULL;
dgriffin65 0:77e050d1fb12 214
dgriffin65 0:77e050d1fb12 215 //new up an int to store the socket fd
dgriffin65 0:77e050d1fb12 216 *handle = h;
sgnezdov 5:41393623ead4 217 DBG("fd: %d\n", sock_fd);
dgriffin65 0:77e050d1fb12 218 return 0;
dgriffin65 0:77e050d1fb12 219 }
dgriffin65 0:77e050d1fb12 220
dgriffin65 1:2dee44ea52a9 221 void W5500Interface::signal_event(nsapi_socket_t handle)
dgriffin65 1:2dee44ea52a9 222 {
sgnezdov 5:41393623ead4 223 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 1:2dee44ea52a9 224 if (SKT(handle)->callback != NULL) {
dgriffin65 1:2dee44ea52a9 225 SKT(handle)->callback(SKT(handle)->callback_data);
dgriffin65 1:2dee44ea52a9 226 }
dgriffin65 1:2dee44ea52a9 227 }
dgriffin65 1:2dee44ea52a9 228
dgriffin65 0:77e050d1fb12 229 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle)
dgriffin65 0:77e050d1fb12 230 {
dgriffin65 0:77e050d1fb12 231 if (handle == NULL) return 0;
sgnezdov 5:41393623ead4 232 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 233 WIZnet_Chip::close(SKT(handle)->fd);
dgriffin65 1:2dee44ea52a9 234
dgriffin65 1:2dee44ea52a9 235 SKT(handle)->fd = -1;
dgriffin65 1:2dee44ea52a9 236
dgriffin65 0:77e050d1fb12 237 return 0;
dgriffin65 0:77e050d1fb12 238 }
dgriffin65 0:77e050d1fb12 239
dgriffin65 0:77e050d1fb12 240 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 241 {
dgriffin65 0:77e050d1fb12 242 if (handle < 0) {
dgriffin65 0:77e050d1fb12 243 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 244 }
sgnezdov 5:41393623ead4 245 DBG("fd: %d, port: %d\n", SKT(handle)->fd, address.get_port());
dgriffin65 0:77e050d1fb12 246
dgriffin65 0:77e050d1fb12 247 switch (SKT(handle)->proto) {
dgriffin65 0:77e050d1fb12 248 case NSAPI_UDP:
dgriffin65 0:77e050d1fb12 249 // set local port
dgriffin65 0:77e050d1fb12 250 if (address.get_port() != 0) {
dgriffin65 0:77e050d1fb12 251 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 252 } else {
dgriffin65 0:77e050d1fb12 253 udp_local_port++;
dgriffin65 0:77e050d1fb12 254 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, udp_local_port);
dgriffin65 0:77e050d1fb12 255 }
dgriffin65 0:77e050d1fb12 256 // set udp protocol
dgriffin65 0:77e050d1fb12 257 WIZnet_Chip::setProtocol(SKT(handle)->fd, UDP);
dgriffin65 0:77e050d1fb12 258 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 259 return 0;
dgriffin65 0:77e050d1fb12 260 case NSAPI_TCP:
dgriffin65 0:77e050d1fb12 261 listen_port = address.get_port();
dgriffin65 0:77e050d1fb12 262 // set TCP protocol
dgriffin65 0:77e050d1fb12 263 WIZnet_Chip::setProtocol(SKT(handle)->fd, TCP);
dgriffin65 0:77e050d1fb12 264 // set local port
dgriffin65 0:77e050d1fb12 265 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 266 // connect the network
dgriffin65 0:77e050d1fb12 267 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 268 return 0;
dgriffin65 0:77e050d1fb12 269 }
dgriffin65 0:77e050d1fb12 270
dgriffin65 0:77e050d1fb12 271 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 272 }
dgriffin65 0:77e050d1fb12 273
dgriffin65 0:77e050d1fb12 274 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog)
dgriffin65 0:77e050d1fb12 275 {
sgnezdov 5:41393623ead4 276 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 277 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 278 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 279 }
dgriffin65 0:77e050d1fb12 280 if (backlog != 1) {
dgriffin65 0:77e050d1fb12 281 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 282 }
dgriffin65 0:77e050d1fb12 283 WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN);
dgriffin65 0:77e050d1fb12 284 return 0;
dgriffin65 0:77e050d1fb12 285 }
dgriffin65 0:77e050d1fb12 286
dgriffin65 0:77e050d1fb12 287 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 288 {
sgnezdov 5:41393623ead4 289 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 290 //check for a valid socket
dgriffin65 0:77e050d1fb12 291 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 292 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 293 }
dgriffin65 0:77e050d1fb12 294
dgriffin65 0:77e050d1fb12 295 //before we attempt to connect, we are not connected
dgriffin65 0:77e050d1fb12 296 SKT(handle)->connected = false;
dgriffin65 0:77e050d1fb12 297
dgriffin65 0:77e050d1fb12 298 //try to connect
dgriffin65 0:77e050d1fb12 299 if (!WIZnet_Chip::connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) {
dgriffin65 0:77e050d1fb12 300 return -1;
dgriffin65 0:77e050d1fb12 301 }
dgriffin65 0:77e050d1fb12 302
dgriffin65 0:77e050d1fb12 303 //we are now connected
dgriffin65 0:77e050d1fb12 304 SKT(handle)->connected = true;
dgriffin65 0:77e050d1fb12 305
dgriffin65 0:77e050d1fb12 306 return 0;
dgriffin65 0:77e050d1fb12 307 }
dgriffin65 0:77e050d1fb12 308
dgriffin65 0:77e050d1fb12 309 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
dgriffin65 0:77e050d1fb12 310 {
sgnezdov 5:41393623ead4 311 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 312 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 313 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 314 }
dgriffin65 0:77e050d1fb12 315
dgriffin65 0:77e050d1fb12 316 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 317
dgriffin65 0:77e050d1fb12 318 Timer t;
dgriffin65 0:77e050d1fb12 319 t.reset();
dgriffin65 0:77e050d1fb12 320 t.start();
dgriffin65 1:2dee44ea52a9 321
dgriffin65 0:77e050d1fb12 322 while(1) {
dgriffin65 1:2dee44ea52a9 323 //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) {
dgriffin65 1:2dee44ea52a9 324 // printf("W5500Interface::socket_accept, timed out\r\n");
dgriffin65 1:2dee44ea52a9 325 // return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 1:2dee44ea52a9 326 //}
dgriffin65 1:2dee44ea52a9 327
dgriffin65 1:2dee44ea52a9 328 nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR);
dgriffin65 1:2dee44ea52a9 329
dgriffin65 1:2dee44ea52a9 330 if (err == SOCK_ESTABLISHED) {
dgriffin65 0:77e050d1fb12 331 break;
dgriffin65 0:77e050d1fb12 332 }
dgriffin65 0:77e050d1fb12 333 }
dgriffin65 0:77e050d1fb12 334
dgriffin65 1:2dee44ea52a9 335 //get socket for the connection
dgriffin65 1:2dee44ea52a9 336 *handle = get_sock(SKT(server)->fd);
dgriffin65 1:2dee44ea52a9 337
dgriffin65 1:2dee44ea52a9 338 if (!(*handle)) {
sgnezdov 5:41393623ead4 339 error("No more sockets for binding");
dgriffin65 1:2dee44ea52a9 340 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 341 }
dgriffin65 1:2dee44ea52a9 342
dgriffin65 0:77e050d1fb12 343 //give it all of the socket info from the server
dgriffin65 0:77e050d1fb12 344 SKT(*handle)->proto = SKT(server)->proto;
dgriffin65 0:77e050d1fb12 345 SKT(*handle)->connected = true;
dgriffin65 1:2dee44ea52a9 346
dgriffin65 0:77e050d1fb12 347 //create a new tcp socket for the server
dgriffin65 0:77e050d1fb12 348 SKT(server)->fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 349 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 350 error("Unable to open a new socket");
dgriffin65 0:77e050d1fb12 351 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 352 }
dgriffin65 0:77e050d1fb12 353
dgriffin65 0:77e050d1fb12 354 SKT(server)->proto = NSAPI_TCP;
dgriffin65 0:77e050d1fb12 355 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 356
dgriffin65 0:77e050d1fb12 357 SocketAddress _addr;
dgriffin65 0:77e050d1fb12 358 _addr.set_port(listen_port);
dgriffin65 0:77e050d1fb12 359
dgriffin65 0:77e050d1fb12 360 // and then, for the next connection, server socket should be assigned new one.
dgriffin65 0:77e050d1fb12 361 if (socket_bind(server, _addr) < 0) {
sgnezdov 4:80e302a610fd 362 error("No more sockets for binding");
dgriffin65 0:77e050d1fb12 363 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 364 }
dgriffin65 0:77e050d1fb12 365
dgriffin65 0:77e050d1fb12 366 if (socket_listen(server, 1) < 0) {
dgriffin65 1:2dee44ea52a9 367 error("No more sockets for listening");
dgriffin65 0:77e050d1fb12 368 }
dgriffin65 0:77e050d1fb12 369
dgriffin65 0:77e050d1fb12 370 if (address) {
dgriffin65 0:77e050d1fb12 371 uint32_t ip = WIZnet_Chip::sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR);
dgriffin65 0:77e050d1fb12 372 char host[17];
dgriffin65 0:77e050d1fb12 373 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 374 int port = WIZnet_Chip::sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT);
dgriffin65 0:77e050d1fb12 375
dgriffin65 0:77e050d1fb12 376 _addr.set_ip_address(host);
dgriffin65 0:77e050d1fb12 377 _addr.set_port(port);
dgriffin65 0:77e050d1fb12 378 *address = _addr;
dgriffin65 0:77e050d1fb12 379 }
dgriffin65 0:77e050d1fb12 380
dgriffin65 0:77e050d1fb12 381 return 0;
dgriffin65 0:77e050d1fb12 382 }
dgriffin65 0:77e050d1fb12 383
dgriffin65 0:77e050d1fb12 384 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 385 {
sgnezdov 5:41393623ead4 386 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 387 int writtenLen = 0;
dgriffin65 0:77e050d1fb12 388 while (writtenLen < size) {
dgriffin65 0:77e050d1fb12 389 int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 390 if (_size < 0) {
dgriffin65 0:77e050d1fb12 391 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 392 }
dgriffin65 0:77e050d1fb12 393 if (_size > (size-writtenLen)) {
dgriffin65 0:77e050d1fb12 394 _size = (size-writtenLen);
dgriffin65 0:77e050d1fb12 395 }
dgriffin65 0:77e050d1fb12 396 int ret = WIZnet_Chip::send(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 397 if (ret < 0) {
sgnezdov 5:41393623ead4 398 DBG("returning error -1\n");
dgriffin65 0:77e050d1fb12 399 return -1;
dgriffin65 0:77e050d1fb12 400 }
dgriffin65 0:77e050d1fb12 401 writtenLen += ret;
dgriffin65 0:77e050d1fb12 402 }
dgriffin65 0:77e050d1fb12 403 return writtenLen;
dgriffin65 0:77e050d1fb12 404 }
dgriffin65 0:77e050d1fb12 405
dgriffin65 0:77e050d1fb12 406 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 407 {
sgnezdov 5:41393623ead4 408 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 409 // add to cover exception.
dgriffin65 0:77e050d1fb12 410 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) {
dgriffin65 0:77e050d1fb12 411 return -1;
dgriffin65 0:77e050d1fb12 412 }
dgriffin65 0:77e050d1fb12 413
dgriffin65 0:77e050d1fb12 414 int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 415
dgriffin65 0:77e050d1fb12 416 if (_size < 0) {
dgriffin65 0:77e050d1fb12 417 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 418 }
dgriffin65 0:77e050d1fb12 419
dgriffin65 0:77e050d1fb12 420 if (_size > size) {
dgriffin65 0:77e050d1fb12 421 _size = size;
dgriffin65 0:77e050d1fb12 422 }
dgriffin65 0:77e050d1fb12 423 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 424 }
dgriffin65 0:77e050d1fb12 425
dgriffin65 0:77e050d1fb12 426 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
dgriffin65 0:77e050d1fb12 427 const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 428 {
sgnezdov 5:41393623ead4 429 DBG("fd: %d, ip: %s:%d\n", SKT(handle)->fd, address.get_ip_address(), address.get_port());
sgnezdov 4:80e302a610fd 430 if (WIZnet_Chip::is_closed(SKT(handle)->fd)) {
sgnezdov 4:80e302a610fd 431 nsapi_error_t err = socket_bind(handle, address);
sgnezdov 4:80e302a610fd 432 if (err < 0) {
sgnezdov 5:41393623ead4 433 DBG("failed to bind socket: %d\n", err);
sgnezdov 4:80e302a610fd 434 return err;
sgnezdov 4:80e302a610fd 435 }
sgnezdov 4:80e302a610fd 436 }
sgnezdov 3:61ff27ed8355 437 //compare with original: int size = eth->wait_writeable(_sock_fd, _blocking ? -1 : _timeout, length-1);
sgnezdov 3:61ff27ed8355 438 int len = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1);
dgriffin65 0:77e050d1fb12 439 if (len < 0) {
sgnezdov 5:41393623ead4 440 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n");
dgriffin65 0:77e050d1fb12 441 return NSAPI_ERROR_WOULD_BLOCK;;
dgriffin65 0:77e050d1fb12 442 }
dgriffin65 0:77e050d1fb12 443
dgriffin65 0:77e050d1fb12 444 // set remote host
dgriffin65 0:77e050d1fb12 445 WIZnet_Chip::sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address());
dgriffin65 0:77e050d1fb12 446 // set remote port
dgriffin65 0:77e050d1fb12 447 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port());
sgnezdov 3:61ff27ed8355 448
sgnezdov 4:80e302a610fd 449 nsapi_size_or_error_t err = WIZnet_Chip::send(SKT(handle)->fd, (const char*)data, size);
sgnezdov 5:41393623ead4 450 DBG("rv: %d, size: %d\n", err, size);
sgnezdov 5:41393623ead4 451 #if w5500_INTF_DBG
sgnezdov 4:80e302a610fd 452 if (err > 0) {
sgnezdov 4:80e302a610fd 453 debug("[socket_sendto] data: ");
sgnezdov 4:80e302a610fd 454 for(int i = 0; i < err; i++) {
sgnezdov 4:80e302a610fd 455 if ((i%16) == 0) {
sgnezdov 4:80e302a610fd 456 debug("\n");
sgnezdov 4:80e302a610fd 457 }
sgnezdov 5:41393623ead4 458 debug(" %02x", ((uint8_t*)data)[i]);
sgnezdov 4:80e302a610fd 459 }
sgnezdov 4:80e302a610fd 460 if ((err-1%16) != 0) {
sgnezdov 4:80e302a610fd 461 debug("\n");
sgnezdov 4:80e302a610fd 462 }
sgnezdov 4:80e302a610fd 463 }
sgnezdov 5:41393623ead4 464 #endif
sgnezdov 4:80e302a610fd 465 return err;
dgriffin65 0:77e050d1fb12 466 }
dgriffin65 0:77e050d1fb12 467
dgriffin65 0:77e050d1fb12 468 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
dgriffin65 0:77e050d1fb12 469 void *buffer, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 470 {
sgnezdov 5:41393623ead4 471 DBG("fd: %d\n", SKT(handle)->fd);
dgriffin65 0:77e050d1fb12 472 //check for null pointers
sgnezdov 4:80e302a610fd 473 if (buffer == NULL) {
sgnezdov 5:41393623ead4 474 DBG("buffer is NULL; receive is ABORTED\n");
sgnezdov 4:80e302a610fd 475 return -1;
sgnezdov 4:80e302a610fd 476 }
sgnezdov 4:80e302a610fd 477
dgriffin65 0:77e050d1fb12 478 uint8_t info[8];
dgriffin65 0:77e050d1fb12 479 int len = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info));
dgriffin65 0:77e050d1fb12 480 if (len < 0) {
sgnezdov 5:41393623ead4 481 DBG("error: NSAPI_ERROR_WOULD_BLOCK\n");
dgriffin65 0:77e050d1fb12 482 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 483 }
dgriffin65 0:77e050d1fb12 484
dgriffin65 0:77e050d1fb12 485 //receive endpoint information
dgriffin65 0:77e050d1fb12 486 WIZnet_Chip::recv(SKT(handle)->fd, (char*)info, sizeof(info));
dgriffin65 0:77e050d1fb12 487
dgriffin65 0:77e050d1fb12 488 char addr[17];
dgriffin65 0:77e050d1fb12 489 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]);
dgriffin65 0:77e050d1fb12 490 uint16_t port = info[4]<<8|info[5];
sgnezdov 4:80e302a610fd 491 // original behavior was to terminate execution if address is NULL
sgnezdov 4:80e302a610fd 492 if (address != NULL) {
sgnezdov 5:41393623ead4 493 //DBG("[socket_recvfrom] warn: addressis NULL");
sgnezdov 4:80e302a610fd 494 address->set_ip_address(addr);
sgnezdov 4:80e302a610fd 495 address->set_port(port);
sgnezdov 4:80e302a610fd 496 }
dgriffin65 0:77e050d1fb12 497
dgriffin65 0:77e050d1fb12 498 int udp_size = info[6]<<8|info[7];
dgriffin65 0:77e050d1fb12 499
dgriffin65 0:77e050d1fb12 500 if (udp_size > (len-sizeof(info))) {
sgnezdov 5:41393623ead4 501 DBG("error: udp_size > (len-sizeof(info))\n");
dgriffin65 0:77e050d1fb12 502 return -1;
dgriffin65 0:77e050d1fb12 503 }
dgriffin65 0:77e050d1fb12 504
dgriffin65 0:77e050d1fb12 505 //receive from socket
sgnezdov 4:80e302a610fd 506 nsapi_size_or_error_t err = WIZnet_Chip::recv(SKT(handle)->fd, (char*)buffer, udp_size);
sgnezdov 5:41393623ead4 507 DBG("rv: %d\n", err);
sgnezdov 5:41393623ead4 508 #if w5500_INTF_DBG
sgnezdov 4:80e302a610fd 509 if (err > 0) {
sgnezdov 4:80e302a610fd 510 debug("[socket_recvfrom] buffer:");
sgnezdov 4:80e302a610fd 511 for(int i = 0; i < err; i++) {
sgnezdov 4:80e302a610fd 512 if ((i%16) == 0) {
sgnezdov 4:80e302a610fd 513 debug("\n");
sgnezdov 4:80e302a610fd 514 }
sgnezdov 5:41393623ead4 515 debug(" %02x", ((uint8_t*)buffer)[i]);
sgnezdov 4:80e302a610fd 516 }
sgnezdov 4:80e302a610fd 517 if ((err-1%16) != 0) {
sgnezdov 4:80e302a610fd 518 debug("\n");
sgnezdov 4:80e302a610fd 519 }
sgnezdov 4:80e302a610fd 520 }
sgnezdov 5:41393623ead4 521 #endif
sgnezdov 4:80e302a610fd 522 return err;
dgriffin65 0:77e050d1fb12 523 }
dgriffin65 0:77e050d1fb12 524
dgriffin65 0:77e050d1fb12 525 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
dgriffin65 0:77e050d1fb12 526 {
dgriffin65 1:2dee44ea52a9 527 if (handle == NULL) return;
sgnezdov 5:41393623ead4 528 DBG("fd: %d, callback: %p\n", SKT(handle)->fd, callback);
dgriffin65 1:2dee44ea52a9 529 SKT(handle)->callback = callback;
dgriffin65 1:2dee44ea52a9 530 SKT(handle)->callback_data = data;
dgriffin65 0:77e050d1fb12 531 }