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