Update of W5500 Interface for mbed-os

Dependents:   PwrCond_mbed5

Revision:
1:2dee44ea52a9
Parent:
0:77e050d1fb12
--- 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