Update of W5500 Interface for mbed-os

Dependents:   PwrCond_mbed5

Files at this revision

API Documentation at this revision

Comitter:
dgriffin65
Date:
Thu Jun 15 20:19:23 2017 +0000
Parent:
0:77e050d1fb12
Commit message:
Updated to mbed-os

Changed in this revision

W5500Interface.cpp Show annotated file Show diff for this revision Revisions of this file
W5500Interface.h Show annotated file Show diff for this revision Revisions of this file
WIZnet/W5500.cpp Show annotated file Show diff for this revision Revisions of this file
WIZnet/W5500.h Show annotated file Show diff for this revision Revisions of this file
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: