W5500 from SeeedStudio on NUCLEO-L476RG

Dependents:   coap-example Borsch coap-example

Fork of W5500Interface by AMETEK Powervar

Committer:
dgriffin65
Date:
Thu Jun 15 20:19:23 2017 +0000
Revision:
1:2dee44ea52a9
Parent:
0:77e050d1fb12
Child:
2:06b6f9f7c071
Updated to mbed-os

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)
dgriffin65 1:2dee44ea52a9 37 #define w5500_WAIT_TIMEOUT 0
dgriffin65 0:77e050d1fb12 38 #define w5500_ACCEPT_TIMEOUT 3000
dgriffin65 0:77e050d1fb12 39
dgriffin65 0:77e050d1fb12 40 /* Interface implementation */
dgriffin65 0:77e050d1fb12 41
dgriffin65 0:77e050d1fb12 42 W5500Interface::W5500Interface(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 43 WIZnet_Chip(mosi, miso, sclk, cs, reset)
dgriffin65 0:77e050d1fb12 44 {
dgriffin65 0:77e050d1fb12 45 ip_set = false;
dgriffin65 0:77e050d1fb12 46 init();
dgriffin65 0:77e050d1fb12 47 }
dgriffin65 0:77e050d1fb12 48
dgriffin65 0:77e050d1fb12 49 W5500Interface::W5500Interface(SPI* spi, PinName cs, PinName reset) :
dgriffin65 0:77e050d1fb12 50 WIZnet_Chip(spi, cs, reset)
dgriffin65 0:77e050d1fb12 51 {
dgriffin65 0:77e050d1fb12 52 ip_set = false;
dgriffin65 0:77e050d1fb12 53 init();
dgriffin65 0:77e050d1fb12 54 }
dgriffin65 0:77e050d1fb12 55
dgriffin65 1:2dee44ea52a9 56 w5500_socket* W5500Interface::get_sock(int fd)
dgriffin65 1:2dee44ea52a9 57 {
dgriffin65 1:2dee44ea52a9 58 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 59 if (w5500_sockets[i].fd == -1) {
dgriffin65 1:2dee44ea52a9 60 w5500_sockets[i].fd = fd;
dgriffin65 1:2dee44ea52a9 61 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 62 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 63 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 64 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 65 return &w5500_sockets[i];
dgriffin65 1:2dee44ea52a9 66 }
dgriffin65 1:2dee44ea52a9 67 }
dgriffin65 1:2dee44ea52a9 68 return NULL;
dgriffin65 1:2dee44ea52a9 69 }
dgriffin65 1:2dee44ea52a9 70
dgriffin65 1:2dee44ea52a9 71 void W5500Interface::init_socks()
dgriffin65 1:2dee44ea52a9 72 {
dgriffin65 1:2dee44ea52a9 73 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 74 w5500_sockets[i].fd = -1;
dgriffin65 1:2dee44ea52a9 75 w5500_sockets[i].proto = NSAPI_TCP;
dgriffin65 1:2dee44ea52a9 76 w5500_sockets[i].callback = NULL;
dgriffin65 1:2dee44ea52a9 77 w5500_sockets[i].callback_data = NULL;
dgriffin65 1:2dee44ea52a9 78 w5500_sockets[i].connected = false;
dgriffin65 1:2dee44ea52a9 79 }
dgriffin65 1:2dee44ea52a9 80
dgriffin65 1:2dee44ea52a9 81 //initialize the socket isr
dgriffin65 1:2dee44ea52a9 82 _daemon = new Thread(osPriorityNormal, 1024);
dgriffin65 1:2dee44ea52a9 83 _daemon->start(callback(this, &W5500Interface::daemon));
dgriffin65 1:2dee44ea52a9 84 }
dgriffin65 1:2dee44ea52a9 85
dgriffin65 0:77e050d1fb12 86 int W5500Interface::init()
dgriffin65 0:77e050d1fb12 87 {
dgriffin65 0:77e050d1fb12 88 WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0"
dgriffin65 1:2dee44ea52a9 89 //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); //
dgriffin65 0:77e050d1fb12 90 reset();
dgriffin65 1:2dee44ea52a9 91 init_socks();
dgriffin65 0:77e050d1fb12 92 return 0;
dgriffin65 0:77e050d1fb12 93 }
dgriffin65 0:77e050d1fb12 94
dgriffin65 0:77e050d1fb12 95 int W5500Interface::init(uint8_t * mac)
dgriffin65 0:77e050d1fb12 96 {
dgriffin65 0:77e050d1fb12 97 //
dgriffin65 0:77e050d1fb12 98 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 99 //
dgriffin65 0:77e050d1fb12 100 reset();
dgriffin65 0:77e050d1fb12 101 setmac();
dgriffin65 1:2dee44ea52a9 102 init_socks();
dgriffin65 0:77e050d1fb12 103 return 0;
dgriffin65 0:77e050d1fb12 104 }
dgriffin65 0:77e050d1fb12 105
dgriffin65 0:77e050d1fb12 106 // add this function, because sometimes no needed MAC address in init calling.
dgriffin65 0:77e050d1fb12 107 int W5500Interface::init(const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 108 {
dgriffin65 0:77e050d1fb12 109 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 110 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 111 ip_set = true;
dgriffin65 0:77e050d1fb12 112 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 113 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 114 reset();
dgriffin65 0:77e050d1fb12 115
dgriffin65 0:77e050d1fb12 116 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 117 setip();
dgriffin65 1:2dee44ea52a9 118 init_socks();
dgriffin65 0:77e050d1fb12 119
dgriffin65 0:77e050d1fb12 120 return 0;
dgriffin65 0:77e050d1fb12 121 }
dgriffin65 0:77e050d1fb12 122
dgriffin65 0:77e050d1fb12 123 int W5500Interface::init(uint8_t * mac, const char* ip, const char* mask, const char* gateway)
dgriffin65 0:77e050d1fb12 124 {
dgriffin65 0:77e050d1fb12 125 //
dgriffin65 0:77e050d1fb12 126 for (int i =0; i < 6; i++) this->mac[i] = mac[i];
dgriffin65 0:77e050d1fb12 127 //
dgriffin65 0:77e050d1fb12 128 this->ip = str_to_ip(ip);
dgriffin65 0:77e050d1fb12 129 strcpy(ip_string, ip);
dgriffin65 0:77e050d1fb12 130 ip_set = true;
dgriffin65 0:77e050d1fb12 131 this->netmask = str_to_ip(mask);
dgriffin65 0:77e050d1fb12 132 this->gateway = str_to_ip(gateway);
dgriffin65 0:77e050d1fb12 133 reset();
dgriffin65 0:77e050d1fb12 134
dgriffin65 0:77e050d1fb12 135 // @Jul. 8. 2014 add code. should be called to write chip.
dgriffin65 0:77e050d1fb12 136 setmac();
dgriffin65 0:77e050d1fb12 137 setip();
dgriffin65 1:2dee44ea52a9 138 init_socks();
dgriffin65 0:77e050d1fb12 139
dgriffin65 0:77e050d1fb12 140 return 0;
dgriffin65 0:77e050d1fb12 141 }
dgriffin65 0:77e050d1fb12 142
dgriffin65 1:2dee44ea52a9 143 void W5500Interface::daemon () {
dgriffin65 1:2dee44ea52a9 144 for (;;) {
dgriffin65 1:2dee44ea52a9 145 for (int i=0; i<MAX_SOCK_NUM ; i++) {
dgriffin65 1:2dee44ea52a9 146 if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) {
dgriffin65 1:2dee44ea52a9 147 int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR);
dgriffin65 1:2dee44ea52a9 148 if (size > 0) {
dgriffin65 1:2dee44ea52a9 149 led1 = !led1;
dgriffin65 1:2dee44ea52a9 150 w5500_sockets[i].callback(w5500_sockets[i].callback_data);
dgriffin65 1:2dee44ea52a9 151 }
dgriffin65 1:2dee44ea52a9 152 }
dgriffin65 1:2dee44ea52a9 153 }
dgriffin65 1:2dee44ea52a9 154 wait(0.2);
dgriffin65 1:2dee44ea52a9 155 }
dgriffin65 1:2dee44ea52a9 156 }
dgriffin65 1:2dee44ea52a9 157
dgriffin65 0:77e050d1fb12 158 int W5500Interface::connect()
dgriffin65 0:77e050d1fb12 159 {
dgriffin65 0:77e050d1fb12 160 if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE;
dgriffin65 0:77e050d1fb12 161 return 0;
dgriffin65 0:77e050d1fb12 162 }
dgriffin65 0:77e050d1fb12 163
dgriffin65 0:77e050d1fb12 164 int W5500Interface::disconnect()
dgriffin65 0:77e050d1fb12 165 {
dgriffin65 0:77e050d1fb12 166 WIZnet_Chip::disconnect();
dgriffin65 0:77e050d1fb12 167 return 0;
dgriffin65 0:77e050d1fb12 168 }
dgriffin65 0:77e050d1fb12 169
dgriffin65 0:77e050d1fb12 170 const char *W5500Interface::get_ip_address()
dgriffin65 0:77e050d1fb12 171 {
dgriffin65 0:77e050d1fb12 172 uint32_t ip = reg_rd<uint32_t>(SIPR);
dgriffin65 0:77e050d1fb12 173 snprintf(ip_string, sizeof(ip_string), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 174 return ip_string;
dgriffin65 0:77e050d1fb12 175 }
dgriffin65 0:77e050d1fb12 176
dgriffin65 0:77e050d1fb12 177 const char *W5500Interface::get_mac_address()
dgriffin65 0:77e050d1fb12 178 {
dgriffin65 0:77e050d1fb12 179 uint8_t mac[6];
dgriffin65 0:77e050d1fb12 180 reg_rd_mac(SHAR, mac);
dgriffin65 0:77e050d1fb12 181 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 182 return mac_string;
dgriffin65 0:77e050d1fb12 183 }
dgriffin65 0:77e050d1fb12 184
dgriffin65 0:77e050d1fb12 185 nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
dgriffin65 0:77e050d1fb12 186 {
dgriffin65 0:77e050d1fb12 187 //a socket is created the same way regardless of the protocol
dgriffin65 0:77e050d1fb12 188 int sock_fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 189 if (sock_fd < 0) {
dgriffin65 0:77e050d1fb12 190 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 191 }
dgriffin65 0:77e050d1fb12 192
dgriffin65 1:2dee44ea52a9 193 w5500_socket *h = get_sock(sock_fd);
dgriffin65 0:77e050d1fb12 194
dgriffin65 1:2dee44ea52a9 195 if (!h) {
dgriffin65 1:2dee44ea52a9 196 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 197 }
dgriffin65 1:2dee44ea52a9 198
dgriffin65 1:2dee44ea52a9 199 h->proto = proto;
dgriffin65 1:2dee44ea52a9 200 h->connected = false;
dgriffin65 1:2dee44ea52a9 201 h->callback = NULL;
dgriffin65 1:2dee44ea52a9 202 h->callback_data = NULL;
dgriffin65 0:77e050d1fb12 203
dgriffin65 0:77e050d1fb12 204 //new up an int to store the socket fd
dgriffin65 0:77e050d1fb12 205 *handle = h;
dgriffin65 0:77e050d1fb12 206
dgriffin65 0:77e050d1fb12 207 return 0;
dgriffin65 0:77e050d1fb12 208 }
dgriffin65 0:77e050d1fb12 209
dgriffin65 1:2dee44ea52a9 210 void W5500Interface::signal_event(nsapi_socket_t handle)
dgriffin65 1:2dee44ea52a9 211 {
dgriffin65 1:2dee44ea52a9 212 if (SKT(handle)->callback != NULL) {
dgriffin65 1:2dee44ea52a9 213 SKT(handle)->callback(SKT(handle)->callback_data);
dgriffin65 1:2dee44ea52a9 214 }
dgriffin65 1:2dee44ea52a9 215 }
dgriffin65 1:2dee44ea52a9 216
dgriffin65 0:77e050d1fb12 217 nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle)
dgriffin65 0:77e050d1fb12 218 {
dgriffin65 0:77e050d1fb12 219 if (handle == NULL) return 0;
dgriffin65 0:77e050d1fb12 220 WIZnet_Chip::close(SKT(handle)->fd);
dgriffin65 1:2dee44ea52a9 221
dgriffin65 1:2dee44ea52a9 222 SKT(handle)->fd = -1;
dgriffin65 1:2dee44ea52a9 223
dgriffin65 0:77e050d1fb12 224 return 0;
dgriffin65 0:77e050d1fb12 225 }
dgriffin65 0:77e050d1fb12 226
dgriffin65 0:77e050d1fb12 227 nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 228 {
dgriffin65 0:77e050d1fb12 229 if (handle < 0) {
dgriffin65 0:77e050d1fb12 230 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 231 }
dgriffin65 0:77e050d1fb12 232
dgriffin65 0:77e050d1fb12 233 switch (SKT(handle)->proto) {
dgriffin65 0:77e050d1fb12 234 case NSAPI_UDP:
dgriffin65 0:77e050d1fb12 235 // set local port
dgriffin65 0:77e050d1fb12 236 if (address.get_port() != 0) {
dgriffin65 0:77e050d1fb12 237 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 238 } else {
dgriffin65 0:77e050d1fb12 239 udp_local_port++;
dgriffin65 0:77e050d1fb12 240 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, udp_local_port);
dgriffin65 0:77e050d1fb12 241 }
dgriffin65 0:77e050d1fb12 242 // set udp protocol
dgriffin65 0:77e050d1fb12 243 WIZnet_Chip::setProtocol(SKT(handle)->fd, UDP);
dgriffin65 0:77e050d1fb12 244 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 245 return 0;
dgriffin65 0:77e050d1fb12 246 case NSAPI_TCP:
dgriffin65 0:77e050d1fb12 247 listen_port = address.get_port();
dgriffin65 0:77e050d1fb12 248 // set TCP protocol
dgriffin65 0:77e050d1fb12 249 WIZnet_Chip::setProtocol(SKT(handle)->fd, TCP);
dgriffin65 0:77e050d1fb12 250 // set local port
dgriffin65 0:77e050d1fb12 251 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_PORT, address.get_port());
dgriffin65 0:77e050d1fb12 252 // connect the network
dgriffin65 0:77e050d1fb12 253 WIZnet_Chip::scmd(SKT(handle)->fd, OPEN);
dgriffin65 0:77e050d1fb12 254 return 0;
dgriffin65 0:77e050d1fb12 255 }
dgriffin65 0:77e050d1fb12 256
dgriffin65 0:77e050d1fb12 257 return NSAPI_ERROR_DEVICE_ERROR;
dgriffin65 0:77e050d1fb12 258 }
dgriffin65 0:77e050d1fb12 259
dgriffin65 0:77e050d1fb12 260 nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog)
dgriffin65 0:77e050d1fb12 261 {
dgriffin65 0:77e050d1fb12 262 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 263 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 264 }
dgriffin65 0:77e050d1fb12 265 if (backlog != 1) {
dgriffin65 0:77e050d1fb12 266 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 267 }
dgriffin65 0:77e050d1fb12 268 WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN);
dgriffin65 0:77e050d1fb12 269 return 0;
dgriffin65 0:77e050d1fb12 270 }
dgriffin65 0:77e050d1fb12 271
dgriffin65 0:77e050d1fb12 272 nsapi_size_or_error_t W5500Interface::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
dgriffin65 0:77e050d1fb12 273 {
dgriffin65 0:77e050d1fb12 274 //check for a valid socket
dgriffin65 0:77e050d1fb12 275 if (SKT(handle)->fd < 0) {
dgriffin65 0:77e050d1fb12 276 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 277 }
dgriffin65 0:77e050d1fb12 278
dgriffin65 0:77e050d1fb12 279 //before we attempt to connect, we are not connected
dgriffin65 0:77e050d1fb12 280 SKT(handle)->connected = false;
dgriffin65 0:77e050d1fb12 281
dgriffin65 0:77e050d1fb12 282 //try to connect
dgriffin65 0:77e050d1fb12 283 if (!WIZnet_Chip::connect(SKT(handle)->fd, address.get_ip_address(), address.get_port(), 0)) {
dgriffin65 0:77e050d1fb12 284 return -1;
dgriffin65 0:77e050d1fb12 285 }
dgriffin65 0:77e050d1fb12 286
dgriffin65 0:77e050d1fb12 287 //we are now connected
dgriffin65 0:77e050d1fb12 288 SKT(handle)->connected = true;
dgriffin65 0:77e050d1fb12 289
dgriffin65 0:77e050d1fb12 290 return 0;
dgriffin65 0:77e050d1fb12 291 }
dgriffin65 0:77e050d1fb12 292
dgriffin65 0:77e050d1fb12 293 nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)
dgriffin65 0:77e050d1fb12 294 {
dgriffin65 0:77e050d1fb12 295 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 296 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 297 }
dgriffin65 0:77e050d1fb12 298
dgriffin65 0:77e050d1fb12 299 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 300
dgriffin65 0:77e050d1fb12 301 Timer t;
dgriffin65 0:77e050d1fb12 302 t.reset();
dgriffin65 0:77e050d1fb12 303 t.start();
dgriffin65 1:2dee44ea52a9 304
dgriffin65 0:77e050d1fb12 305 while(1) {
dgriffin65 1:2dee44ea52a9 306 //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) {
dgriffin65 1:2dee44ea52a9 307 // printf("W5500Interface::socket_accept, timed out\r\n");
dgriffin65 1:2dee44ea52a9 308 // return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 1:2dee44ea52a9 309 //}
dgriffin65 1:2dee44ea52a9 310
dgriffin65 1:2dee44ea52a9 311 nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR);
dgriffin65 1:2dee44ea52a9 312
dgriffin65 1:2dee44ea52a9 313 if (err == SOCK_ESTABLISHED) {
dgriffin65 0:77e050d1fb12 314 break;
dgriffin65 0:77e050d1fb12 315 }
dgriffin65 0:77e050d1fb12 316 }
dgriffin65 0:77e050d1fb12 317
dgriffin65 1:2dee44ea52a9 318 //get socket for the connection
dgriffin65 1:2dee44ea52a9 319 *handle = get_sock(SKT(server)->fd);
dgriffin65 1:2dee44ea52a9 320
dgriffin65 1:2dee44ea52a9 321 if (!(*handle)) {
dgriffin65 1:2dee44ea52a9 322 error("No more socketa for binding");
dgriffin65 1:2dee44ea52a9 323 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 1:2dee44ea52a9 324 }
dgriffin65 1:2dee44ea52a9 325
dgriffin65 0:77e050d1fb12 326 //give it all of the socket info from the server
dgriffin65 0:77e050d1fb12 327 SKT(*handle)->proto = SKT(server)->proto;
dgriffin65 0:77e050d1fb12 328 SKT(*handle)->connected = true;
dgriffin65 1:2dee44ea52a9 329
dgriffin65 0:77e050d1fb12 330 //create a new tcp socket for the server
dgriffin65 0:77e050d1fb12 331 SKT(server)->fd = WIZnet_Chip::new_socket();
dgriffin65 0:77e050d1fb12 332 if (SKT(server)->fd < 0) {
dgriffin65 0:77e050d1fb12 333 error("Unable to open a new socket");
dgriffin65 0:77e050d1fb12 334 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 335 }
dgriffin65 0:77e050d1fb12 336
dgriffin65 0:77e050d1fb12 337 SKT(server)->proto = NSAPI_TCP;
dgriffin65 0:77e050d1fb12 338 SKT(server)->connected = false;
dgriffin65 0:77e050d1fb12 339
dgriffin65 0:77e050d1fb12 340 SocketAddress _addr;
dgriffin65 0:77e050d1fb12 341 _addr.set_port(listen_port);
dgriffin65 0:77e050d1fb12 342
dgriffin65 0:77e050d1fb12 343 // and then, for the next connection, server socket should be assigned new one.
dgriffin65 0:77e050d1fb12 344 if (socket_bind(server, _addr) < 0) {
dgriffin65 0:77e050d1fb12 345 error("No more socketa for binding");
dgriffin65 0:77e050d1fb12 346 return NSAPI_ERROR_NO_SOCKET;
dgriffin65 0:77e050d1fb12 347 }
dgriffin65 0:77e050d1fb12 348
dgriffin65 0:77e050d1fb12 349 if (socket_listen(server, 1) < 0) {
dgriffin65 1:2dee44ea52a9 350 error("No more sockets for listening");
dgriffin65 0:77e050d1fb12 351 }
dgriffin65 0:77e050d1fb12 352
dgriffin65 0:77e050d1fb12 353 if (address) {
dgriffin65 0:77e050d1fb12 354 uint32_t ip = WIZnet_Chip::sreg<uint32_t>(SKT(*handle)->fd, Sn_DIPR);
dgriffin65 0:77e050d1fb12 355 char host[17];
dgriffin65 0:77e050d1fb12 356 snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
dgriffin65 0:77e050d1fb12 357 int port = WIZnet_Chip::sreg<uint16_t>(SKT(*handle)->fd, Sn_DPORT);
dgriffin65 0:77e050d1fb12 358
dgriffin65 0:77e050d1fb12 359 _addr.set_ip_address(host);
dgriffin65 0:77e050d1fb12 360 _addr.set_port(port);
dgriffin65 0:77e050d1fb12 361 *address = _addr;
dgriffin65 0:77e050d1fb12 362 }
dgriffin65 0:77e050d1fb12 363
dgriffin65 0:77e050d1fb12 364 return 0;
dgriffin65 0:77e050d1fb12 365 }
dgriffin65 0:77e050d1fb12 366
dgriffin65 0:77e050d1fb12 367 nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 368 {
dgriffin65 0:77e050d1fb12 369 int writtenLen = 0;
dgriffin65 0:77e050d1fb12 370 while (writtenLen < size) {
dgriffin65 0:77e050d1fb12 371 int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 372 if (_size < 0) {
dgriffin65 0:77e050d1fb12 373 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 374 }
dgriffin65 0:77e050d1fb12 375 if (_size > (size-writtenLen)) {
dgriffin65 0:77e050d1fb12 376 _size = (size-writtenLen);
dgriffin65 0:77e050d1fb12 377 }
dgriffin65 0:77e050d1fb12 378 int ret = WIZnet_Chip::send(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 379 if (ret < 0) {
dgriffin65 0:77e050d1fb12 380 return -1;
dgriffin65 0:77e050d1fb12 381 }
dgriffin65 0:77e050d1fb12 382 writtenLen += ret;
dgriffin65 0:77e050d1fb12 383 }
dgriffin65 0:77e050d1fb12 384 return writtenLen;
dgriffin65 0:77e050d1fb12 385 }
dgriffin65 0:77e050d1fb12 386
dgriffin65 0:77e050d1fb12 387 nsapi_size_or_error_t W5500Interface::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 388 {
dgriffin65 0:77e050d1fb12 389 // add to cover exception.
dgriffin65 0:77e050d1fb12 390 if ((SKT(handle)->fd < 0) || !SKT(handle)->connected) {
dgriffin65 0:77e050d1fb12 391 return -1;
dgriffin65 0:77e050d1fb12 392 }
dgriffin65 0:77e050d1fb12 393
dgriffin65 0:77e050d1fb12 394 int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT);
dgriffin65 0:77e050d1fb12 395
dgriffin65 0:77e050d1fb12 396 if (_size < 0) {
dgriffin65 0:77e050d1fb12 397 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 398 }
dgriffin65 0:77e050d1fb12 399
dgriffin65 0:77e050d1fb12 400 if (_size > size) {
dgriffin65 0:77e050d1fb12 401 _size = size;
dgriffin65 0:77e050d1fb12 402 }
dgriffin65 0:77e050d1fb12 403 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)data, (int)_size);
dgriffin65 0:77e050d1fb12 404 }
dgriffin65 0:77e050d1fb12 405
dgriffin65 0:77e050d1fb12 406 nsapi_size_or_error_t W5500Interface::socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
dgriffin65 0:77e050d1fb12 407 const void *data, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 408 {
dgriffin65 0:77e050d1fb12 409 int len = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, size-1);
dgriffin65 0:77e050d1fb12 410 if (len < 0) {
dgriffin65 0:77e050d1fb12 411 return NSAPI_ERROR_WOULD_BLOCK;;
dgriffin65 0:77e050d1fb12 412 }
dgriffin65 0:77e050d1fb12 413
dgriffin65 0:77e050d1fb12 414 // set remote host
dgriffin65 0:77e050d1fb12 415 WIZnet_Chip::sreg_ip(SKT(handle)->fd, Sn_DIPR, address.get_ip_address());
dgriffin65 0:77e050d1fb12 416 // set remote port
dgriffin65 0:77e050d1fb12 417 WIZnet_Chip::sreg<uint16_t>(SKT(handle)->fd, Sn_DPORT, address.get_port());
dgriffin65 0:77e050d1fb12 418
dgriffin65 0:77e050d1fb12 419 return WIZnet_Chip::send(SKT(handle)->fd, (const char*)data, size);
dgriffin65 0:77e050d1fb12 420 }
dgriffin65 0:77e050d1fb12 421
dgriffin65 0:77e050d1fb12 422 nsapi_size_or_error_t W5500Interface::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
dgriffin65 0:77e050d1fb12 423 void *buffer, nsapi_size_t size)
dgriffin65 0:77e050d1fb12 424 {
dgriffin65 0:77e050d1fb12 425 //check for null pointers
dgriffin65 0:77e050d1fb12 426 if (address == NULL || buffer == NULL) return -1;
dgriffin65 0:77e050d1fb12 427
dgriffin65 0:77e050d1fb12 428 uint8_t info[8];
dgriffin65 0:77e050d1fb12 429 int len = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT, sizeof(info));
dgriffin65 0:77e050d1fb12 430 if (len < 0) {
dgriffin65 0:77e050d1fb12 431 return NSAPI_ERROR_WOULD_BLOCK;
dgriffin65 0:77e050d1fb12 432 }
dgriffin65 0:77e050d1fb12 433
dgriffin65 0:77e050d1fb12 434 //receive endpoint information
dgriffin65 0:77e050d1fb12 435 WIZnet_Chip::recv(SKT(handle)->fd, (char*)info, sizeof(info));
dgriffin65 0:77e050d1fb12 436
dgriffin65 0:77e050d1fb12 437 char addr[17];
dgriffin65 0:77e050d1fb12 438 snprintf(addr, sizeof(addr), "%d.%d.%d.%d", info[0], info[1], info[2], info[3]);
dgriffin65 0:77e050d1fb12 439 uint16_t port = info[4]<<8|info[5];
dgriffin65 0:77e050d1fb12 440 address->set_ip_address(addr);
dgriffin65 0:77e050d1fb12 441 address->set_port(port);
dgriffin65 0:77e050d1fb12 442
dgriffin65 0:77e050d1fb12 443 int udp_size = info[6]<<8|info[7];
dgriffin65 0:77e050d1fb12 444
dgriffin65 0:77e050d1fb12 445 if (udp_size > (len-sizeof(info))) {
dgriffin65 0:77e050d1fb12 446 return -1;
dgriffin65 0:77e050d1fb12 447 }
dgriffin65 0:77e050d1fb12 448
dgriffin65 0:77e050d1fb12 449 //receive from socket
dgriffin65 0:77e050d1fb12 450 return WIZnet_Chip::recv(SKT(handle)->fd, (char*)buffer, udp_size);
dgriffin65 0:77e050d1fb12 451 }
dgriffin65 0:77e050d1fb12 452
dgriffin65 0:77e050d1fb12 453 void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
dgriffin65 0:77e050d1fb12 454 {
dgriffin65 1:2dee44ea52a9 455 if (handle == NULL) return;
dgriffin65 1:2dee44ea52a9 456
dgriffin65 1:2dee44ea52a9 457 SKT(handle)->callback = callback;
dgriffin65 1:2dee44ea52a9 458 SKT(handle)->callback_data = data;
dgriffin65 0:77e050d1fb12 459 }