W5500 from SeeedStudio on NUCLEO-L476RG
Dependents: coap-example Borsch coap-example
Fork of W5500Interface by
W5500Interface.cpp@1:2dee44ea52a9, 2017-06-15 (annotated)
- 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?
User | Revision | Line number | New 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 | } |