Update of W5500 Interface for mbed-os
Revision 1:2dee44ea52a9, committed 2017-06-15
- Comitter:
- dgriffin65
- Date:
- Thu Jun 15 20:19:23 2017 +0000
- Parent:
- 0:77e050d1fb12
- Commit message:
- Updated to mbed-os
Changed in this revision
diff -r 77e050d1fb12 -r 2dee44ea52a9 W5500Interface.cpp --- a/W5500Interface.cpp Fri Jun 02 22:00:49 2017 +0000 +++ b/W5500Interface.cpp Thu Jun 15 20:19:23 2017 +0000 @@ -29,18 +29,12 @@ #include "mbed.h" #include "W5500Interface.h" -struct w5500_socket { - int fd; - nsapi_protocol_t proto; - //bool blocking; - //int timeout; - bool connected; -}; - static int udp_local_port = 0; +DigitalOut led1(LED1); + #define SKT(h) ((w5500_socket*)h) -#define w5500_WAIT_TIMEOUT 1000 +#define w5500_WAIT_TIMEOUT 0 #define w5500_ACCEPT_TIMEOUT 3000 /* Interface implementation */ @@ -59,10 +53,42 @@ init(); } +w5500_socket* W5500Interface::get_sock(int fd) +{ + for (int i=0; i<MAX_SOCK_NUM ; i++) { + if (w5500_sockets[i].fd == -1) { + w5500_sockets[i].fd = fd; + w5500_sockets[i].proto = NSAPI_TCP; + w5500_sockets[i].connected = false; + w5500_sockets[i].callback = NULL; + w5500_sockets[i].callback_data = NULL; + return &w5500_sockets[i]; + } + } + return NULL; +} + +void W5500Interface::init_socks() +{ + for (int i=0; i<MAX_SOCK_NUM ; i++) { + w5500_sockets[i].fd = -1; + w5500_sockets[i].proto = NSAPI_TCP; + w5500_sockets[i].callback = NULL; + w5500_sockets[i].callback_data = NULL; + w5500_sockets[i].connected = false; + } + + //initialize the socket isr + _daemon = new Thread(osPriorityNormal, 1024); + _daemon->start(callback(this, &W5500Interface::daemon)); +} + int W5500Interface::init() { WIZnet_Chip::reg_wr<uint32_t>(SIPR, 0x00000000); // local ip "0.0.0.0" + //WIZnet_Chip::reg_wr<uint8_t>(SIMR, 0xFF); // reset(); + init_socks(); return 0; } @@ -73,6 +99,7 @@ // reset(); setmac(); + init_socks(); return 0; } @@ -88,6 +115,7 @@ // @Jul. 8. 2014 add code. should be called to write chip. setip(); + init_socks(); return 0; } @@ -107,10 +135,26 @@ // @Jul. 8. 2014 add code. should be called to write chip. setmac(); setip(); + init_socks(); return 0; } +void W5500Interface::daemon () { + for (;;) { + for (int i=0; i<MAX_SOCK_NUM ; i++) { + if (w5500_sockets[i].fd > 0 && w5500_sockets[i].callback) { + int size = sreg<uint16_t>(w5500_sockets[i].fd, Sn_RX_RSR); + if (size > 0) { + led1 = !led1; + w5500_sockets[i].callback(w5500_sockets[i].callback_data); + } + } + } + wait(0.2); + } +} + int W5500Interface::connect() { if (WIZnet_Chip::setip() == false) return NSAPI_ERROR_DHCP_FAILURE; @@ -140,40 +184,48 @@ nsapi_error_t W5500Interface::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) { - printf("W5500Interface::socket_open h = 0x%08x\r\n", *handle); //a socket is created the same way regardless of the protocol int sock_fd = WIZnet_Chip::new_socket(); if (sock_fd < 0) { - printf("W5500Interface::socket_open NSAPI_ERROR_NO_SOCKETT\r\n"); return NSAPI_ERROR_NO_SOCKET; } - w5500_socket *h = new w5500_socket; + w5500_socket *h = get_sock(sock_fd); - h->fd = sock_fd; - h->proto = proto; - h->connected = false; + if (!h) { + return NSAPI_ERROR_NO_SOCKET; + } + + h->proto = proto; + h->connected = false; + h->callback = NULL; + h->callback_data = NULL; //new up an int to store the socket fd *handle = h; - printf("W5500Interface::socket_open h = 0x%08x\r\n", h); - return 0; } +void W5500Interface::signal_event(nsapi_socket_t handle) +{ + if (SKT(handle)->callback != NULL) { + SKT(handle)->callback(SKT(handle)->callback_data); + } +} + nsapi_error_t W5500Interface::socket_close(nsapi_socket_t handle) { - printf("W5500Interface::socket_close 0x%08x\r\n", handle); if (handle == NULL) return 0; WIZnet_Chip::close(SKT(handle)->fd); - delete SKT(handle); + + SKT(handle)->fd = -1; + return 0; } nsapi_error_t W5500Interface::socket_bind(nsapi_socket_t handle, const SocketAddress &address) { - printf("W5500Interface::socket_bind\r\n"); if (handle < 0) { return NSAPI_ERROR_DEVICE_ERROR; } @@ -208,14 +260,11 @@ nsapi_error_t W5500Interface::socket_listen(nsapi_socket_t handle, int backlog) { if (SKT(handle)->fd < 0) { - printf("W5500Interface::socket_listen, error no socket 1\r\n"); return NSAPI_ERROR_NO_SOCKET; } if (backlog != 1) { - printf("W5500Interface::socket_listen, error no socket 2 \r\n"); return NSAPI_ERROR_NO_SOCKET; } - printf("W5500Interface::socket_listen, listening\r\n"); WIZnet_Chip::scmd(SKT(handle)->fd, LISTEN); return 0; } @@ -244,7 +293,6 @@ nsapi_error_t W5500Interface::socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address) { if (SKT(server)->fd < 0) { - printf("W5500Interface::socket_accept, error no socket\r\n"); return NSAPI_ERROR_NO_SOCKET; } @@ -253,25 +301,32 @@ Timer t; t.reset(); t.start(); + while(1) { - if (t.read_ms() > w5500_ACCEPT_TIMEOUT) { - printf("W5500Interface::socket_accept, timed out\r\n"); - return NSAPI_ERROR_WOULD_BLOCK; - } - if (WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR) == SOCK_ESTABLISHED) { - printf("W5500Interface::socket_accept, established connection\r\n"); + //if (t.read_ms() > w5500_ACCEPT_TIMEOUT) { + // printf("W5500Interface::socket_accept, timed out\r\n"); + // return NSAPI_ERROR_WOULD_BLOCK; + //} + + nsapi_error_t err = WIZnet_Chip::sreg<uint8_t>(SKT(server)->fd, Sn_SR); + + if (err == SOCK_ESTABLISHED) { break; } } - //create a new socket for the connection - *handle = new w5500_socket; - + //get socket for the connection + *handle = get_sock(SKT(server)->fd); + + if (!(*handle)) { + error("No more socketa for binding"); + return NSAPI_ERROR_NO_SOCKET; + } + //give it all of the socket info from the server - SKT(*handle)->fd = SKT(server)->fd; SKT(*handle)->proto = SKT(server)->proto; SKT(*handle)->connected = true; - + //create a new tcp socket for the server SKT(server)->fd = WIZnet_Chip::new_socket(); if (SKT(server)->fd < 0) { @@ -285,8 +340,6 @@ SocketAddress _addr; _addr.set_port(listen_port); - printf("opened socket, binding and listening on port %d\r\n", listen_port); - // and then, for the next connection, server socket should be assigned new one. if (socket_bind(server, _addr) < 0) { error("No more socketa for binding"); @@ -294,7 +347,7 @@ } if (socket_listen(server, 1) < 0) { - error("No more socket for listening"); + error("No more sockets for listening"); } if (address) { @@ -313,8 +366,6 @@ nsapi_size_or_error_t W5500Interface::socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size) { - printf("W5500Interface::socket_send\r\n"); - int writtenLen = 0; while (writtenLen < size) { int _size = WIZnet_Chip::wait_writeable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); @@ -340,9 +391,7 @@ return -1; } - printf("WIZnet_Chip::wait_readable fd = 0x%08x, timeout = %d\r\n", SKT(handle)->fd, w5500_WAIT_TIMEOUT); int _size = WIZnet_Chip::wait_readable(SKT(handle)->fd, w5500_WAIT_TIMEOUT); - printf("WIZnet_Chip::wait_readable n = %d\r\n", _size); if (_size < 0) { return NSAPI_ERROR_WOULD_BLOCK; @@ -403,5 +452,8 @@ void W5500Interface::socket_attach(void *handle, void (*callback)(void *), void *data) { - printf("W5500Interface::socket_attach\r\n"); + if (handle == NULL) return; + + SKT(handle)->callback = callback; + SKT(handle)->callback_data = data; } \ No newline at end of file
diff -r 77e050d1fb12 -r 2dee44ea52a9 W5500Interface.h --- a/W5500Interface.h Fri Jun 02 22:00:49 2017 +0000 +++ b/W5500Interface.h Thu Jun 15 20:19:23 2017 +0000 @@ -23,9 +23,22 @@ #include "rtos.h" #include "WIZnet/W5500.h" +/** w5500_socket struct + * W5500 socket + */ + +struct w5500_socket { + int fd; + nsapi_protocol_t proto; + void (*callback)(void *); + void *callback_data; + bool connected; +}; + /** W5500Interface class * Implementation of the NetworkStack for the W5500 */ + class W5500Interface : public NetworkStack, public EthInterface, public WIZnet_Chip { public: @@ -232,6 +245,17 @@ bool ip_set; int listen_port; + + void signal_event(nsapi_socket_t handle); + + //w5500 socket management + struct w5500_socket w5500_sockets[MAX_SOCK_NUM]; + w5500_socket* get_sock(int fd); + void init_socks(); + + Thread *_daemon; + void daemon(); + }; #endif
diff -r 77e050d1fb12 -r 2dee44ea52a9 WIZnet/W5500.cpp --- a/WIZnet/W5500.cpp Fri Jun 02 22:00:49 2017 +0000 +++ b/WIZnet/W5500.cpp Thu Jun 15 20:19:23 2017 +0000 @@ -49,9 +49,7 @@ bool WIZnet_Chip::setmac() { - for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]); - return true; } @@ -184,18 +182,24 @@ int size1, size2; // during the reading Sn_RX_RSR, it has the possible change of this register. // so read twice and get same value then use size information. - do { + while (1) { size1 = sreg<uint16_t>(socket, Sn_RX_RSR); size2 = sreg<uint16_t>(socket, Sn_RX_RSR); - printf("WIZnet_Chip::wait_readable req_size = %d, size1 = %d, size2 = %d\r\n", req_size, size1, size2); + + if (size1 == size2) { + break; + } if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { return NSAPI_ERROR_WOULD_BLOCK; } - } while (size1 != size2); + + if (!is_connected(socket)) { + return -1; + } + } if (size1 > req_size) { - printf("WIZnet_Chip::wait_readable returning %d\r\n", size1); return size1; } if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { @@ -307,6 +311,7 @@ void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len) { + spi->lock(); cs = 0; spi->write(addr >> 8); spi->write(addr & 0xff); @@ -327,10 +332,13 @@ } debug("\r\n"); #endif + spi->unlock(); + } void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len) { + spi->lock(); cs = 0; spi->write(addr >> 8); spi->write(addr & 0xff); @@ -354,6 +362,7 @@ wait_ms(200); } #endif + spi->unlock(); } uint32_t str_to_ip(const char* str)
diff -r 77e050d1fb12 -r 2dee44ea52a9 WIZnet/W5500.h --- a/WIZnet/W5500.h Fri Jun 02 22:00:49 2017 +0000 +++ b/WIZnet/W5500.h Thu Jun 15 20:19:23 2017 +0000 @@ -52,6 +52,8 @@ #define SUBR 0x0005 #define SHAR 0x0009 #define SIPR 0x000f +#define SIR 0x0017 +#define SIMR 0x0018 #define PHYSTATUS 0x0035 // W5500 socket register @@ -68,6 +70,9 @@ #define Sn_TX_WR 0x0024 #define Sn_RX_RSR 0x0026 #define Sn_RX_RD 0x0028 +#define Sn_IMR 0x002C + + class WIZnet_Chip { public: