NuMaker Transfer data UART to Ethernet

Fork of Serial-to-Ethernet by Morgan Du

Revision:
6:014b1a469aed
Parent:
3:9c4210dcdddd
Child:
7:c03b2ed97d94
--- a/main.cpp	Thu Apr 19 14:03:33 2018 +0800
+++ b/main.cpp	Tue Mar 02 10:09:10 2021 +0800
@@ -5,10 +5,9 @@
  * 
  *
  */
- 
 #include "ste_config.h"
 
-/* If define USE_STATIC_IP, specify the default IP address. */
+/* If choose static IP, specify the default IP address here. */
 #if 0
     // private IP address for general purpose
 #define IP_ADDRESS      "192.168.1.2"
@@ -16,25 +15,38 @@
 #define GATEWAY_ADDRESS "192.168.1.1"
 #else
     // private IP address only for test with Windows when DHCP server doesn't exist.
+    // Windows set its LAN IP address to 169.254.xxx.xxx / 255.255.0.0 
 #define IP_ADDRESS      "169.254.108.2"
 #define NETWORK_MASK    "255.255.0.0"
 #define GATEWAY_ADDRESS "169.254.108.1"
 #endif
 
-/* Default configuration for network */
+/* Default IP configuration for Ethernet network */
 S_NET_CONFIG net_config = {IP_STATIC_MODE, IP_ADDRESS, NETWORK_MASK, GATEWAY_ADDRESS};
 
-#if defined (TARGET_NUMAKER_PFM_M487)
-BufferedSerial serial_0(PH_8, PH_9, 256, 4);    // UART1
-BufferedSerial serial_1(PC_12, PC_11, 256, 4);  // UART0
-BufferedSerial serial_2(PA_3, PA_2, 256, 4);  // UART4
+#if defined (TARGET_NUMAKER_PFM_M487) || defined(TARGET_NUMAKER_IOT_M487)
+#if MBED_MAJOR_VERSION <= 5
+BufferSerial serial_0(PB_3, PB_2, 256, 4);    // UART1
+BufferSerial serial_1(PA_5, PA_4, 256, 4);    // UART5
+//BufferSerial serial_2(PB_13, PB_12, 256, 4);  // UART0, Debug
+#else
+BufferSerial serial_0(PB_3, PB_2);    // UART1
+BufferSerial serial_1(PA_5, PA_4);    // UART5
+//BufferSerial serial_2(PB_13, PB_12);  // UART0, Debug
+#endif
 
 #elif defined (TARGET_NUMAKER_PFM_NUC472)
-BufferedSerial serial_0(PH_1, PH_0, 256, 4);    // UART4
-BufferedSerial serial_1(PG_2, PG_1, 256, 4);    // UART0
-BufferedSerial serial_2(PC_11, PC_10, 256, 4);  // UART2
+#if MBED_MAJOR_VERSION <= 5
+BufferSerial serial_0(PH_1, PH_0, 256, 4);    // UART4
+BufferSerial serial_1(PG_2, PG_1, 256, 4);    // UART0
+BufferSerial serial_2(PC_11, PC_10, 256, 4);  // UART2
+#else
+BufferSerial serial_0(PH_1, PH_0);    // UART4
+BufferSerial serial_1(PG_2, PG_1);    // UART0
+BufferSerial serial_2(PC_11, PC_10);  // UART2
+#endif
 
-#elif defined (TARGET_NUMAKER_PFM_M453)
+#elif defined (TARGET_NUMAKER_PFM_M453) || defined(TARGET_NUMAKER_PFM_NANO130) || defined(TARGET_NUMAKER_PFM_M2351)
 #error The board has no Ethernet.
 
 #else
@@ -61,14 +73,12 @@
 #endif
 };
 
-/* UART port to output debug message */
-RawSerial output(USBTX, USBRX);             // UART3 on NuMaker-PFM-NUC472
 EthernetInterface eth;
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
 
 /* Declare the SD card as storage */
-NuSDBlockDevice bd;
+NuSDBlockDevice *bd = new NuSDBlockDevice();
 FATFileSystem fs("fs");
 bool SD_Card_Mounted = FALSE;
 
@@ -86,80 +96,92 @@
     unsigned char s_buf[256];
     int n_len = 0, n_index = 0;
     int s_len = 0, s_index = 0;
+    unsigned int eth_tx_count = 0;
     
     while(1)
     {   
         /*** Network to Serial ***/
         
-        if (n_len < 0 || n_len == n_index)
+        if (n_len == 0)
         {
             // net buffer is empty, try to get new data from network.
             n_len = psocket->recv(n_buf, sizeof(n_buf));
-            if (n_len == NSAPI_ERROR_WOULD_BLOCK)
+            if (n_len == 0)
             {
+                eth_tx_count += 3;
+            }
+            else if (n_len == NSAPI_ERROR_WOULD_BLOCK)
+            {
+                n_len = 0;
             }
             else if (n_len < 0)
             {
                 printf("Socket Recv Err (%d)\r\n", n_len);
-                psocket->close();
                 break;
             }
-            else
-            {
-                n_index = 0;
-            }
         }
         else
         {
-            // send data to serial port.
-            for(;n_index < n_len && pmap->pserial->writeable(); n_index++)
+            n_index += pmap->pserial->write(n_buf+n_index, n_len-n_index);
+            if (n_index == n_len)
             {
-                pmap->pserial->putc(n_buf[n_index]);
+                n_len = 0;
+                n_index = 0;
             }
         }
 
         /*** Serial to Network ***/
-        
+
+        // try to get more data from serial port
+#if MBED_MAJOR_VERSION <= 5        
+        for(; s_index < sizeof(s_buf) && pmap->pserial->readable(); s_index++)
+            s_buf[s_index] = pmap->pserial->getc();
+#else
         if (pmap->pserial->readable())
         {
-            // try to get more data from serial port
-            for(s_index = 0; s_index < sizeof(s_buf) && pmap->pserial->readable(); s_index++)
-                s_buf[s_index] = pmap->pserial->getc();
-            
-            // send all data to network.
-            if (s_index > 0)
+            s_len = pmap->pserial->read(s_buf+s_index, sizeof(s_buf)-s_index);
+            if (s_len > 0)
+                s_index += s_len;
+        }
+#endif
+        
+        if (s_index >= 240 || (s_index != 0 && ++eth_tx_count >= 5))
+        {
+            s_len = psocket->send(s_buf, s_index); 
+
+            if (s_len == NSAPI_ERROR_WOULD_BLOCK)
+            {
+                printf("Socket Send no block.\r\n");
+            }               
+            else if (s_len < 0)
             {
-                s_len = psocket->send(s_buf, s_index); 
-                if (s_len == NSAPI_ERROR_WOULD_BLOCK)
-                {
-                    printf("Socket Send no block.\r\n");
-                }               
-                else if (s_len < 0)
-                {
-                    printf("Socket Send Err (%d)\r\n", s_len);
-                    psocket->close();
-                    break;
-                }
-                else if (s_len != s_index)
-                {
-                    printf("Socket Send not complete.\r\n");
-                    psocket->close();
-                    break;
-                }
+                printf("Socket Send Err (%d)\r\n", s_len);
+                break;
             }
-        }
+            else // s_len >= s_index
+            {
+                unsigned int i;
+
+                // move remain data if existed.
+                for(i=0; s_len < s_index; i++, s_len++)
+                    s_buf[i] = s_buf[s_len];
+
+                s_index = i;
+                eth_tx_count = 0;
+            }
+        }       
     }
 }   
-
+   
 void bridge_net_client(S_PORT_CONFIG *pmap)
 {
     TCPSocket socket;
-    SocketAddress server_address;
+    SocketAddress server_ipaddr;
     nsapi_error_t err;
 
     printf("Thread %x in TCP client mode.\r\n", (unsigned int)pmap);
 
-    if ((err=socket.open(&eth)) < 0)
+    if ((err=socket.open(&eth)) != NSAPI_ERROR_OK)
     {
         printf("TCP socket can't open (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
@@ -168,31 +190,35 @@
     printf("Connecting server %s:%d ...\r\n", pmap->server_addr, pmap->server_port);
     while(1)
     {
-        if ((err=socket.connect(pmap->server_addr, pmap->server_port)) >= 0)
+        server_ipaddr.set_ip_address(pmap->server_addr);
+        server_ipaddr.set_port(pmap->server_port);
+        if ((err=socket.connect(server_ipaddr)) >= 0)
+        {
+            printf("\r\nConnected.");
             break;
+        }
     }
     
-    printf("\r\nConnected.");
-
     socket.set_timeout(1);
     exchange_data(pmap, &socket);
+    socket.close();
 }
 
 void bridge_net_server(S_PORT_CONFIG *pmap)
 {
-    TCPServer tcp_server;
-    TCPSocket client_socket;
-    SocketAddress client_address;
+    TCPSocket tcp_server;
+    TCPSocket *client_socket;
+    SocketAddress client_ipaddr;
     nsapi_error_t err;
     
     printf("Thread %x in TCP server mode.\r\n", (unsigned int)pmap);
     
-    if ((err=tcp_server.open(&eth)) < 0)
+    if ((err=tcp_server.open(&eth)) != NSAPI_ERROR_OK)
     {
         printf("TCP server can't open (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
     }
-    if ((err=tcp_server.bind(eth.get_ip_address(), pmap->port)) < 0)
+    if ((err=tcp_server.bind(pmap->port)) != NSAPI_ERROR_OK)
     {
         printf("TCP server can't bind address and port (%d)(%x).\r\n", err, (unsigned int)pmap);
         return;
@@ -203,36 +229,46 @@
         return;
     }
 
-    client_socket.set_timeout(1);
-
     while(1)
     {   
-        if ((err=tcp_server.accept(&client_socket, &client_address)) < 0)
+        client_socket = tcp_server.accept(&err);
+        if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_WOULD_BLOCK)
         {
             printf("TCP server fail to accept connection (%d)(%x).\r\n", err, (unsigned int)pmap);
             return;
         }
-
-        printf("Connect (%d) from %s:%d ...\r\n", pmap->port, client_address.get_ip_address(), client_address.get_port());
-
-        exchange_data(pmap, &client_socket);        
+        else
+        {
+            client_socket->getpeername(&client_ipaddr);
+            printf("Connect (%d) from %s:%d ...\r\n", pmap->port, client_ipaddr.get_ip_address(), client_ipaddr.get_port());
+  
+            client_socket->set_timeout(1);
+            exchange_data(pmap, client_socket);
+            client_socket->close();
+        }
     }
 }   
 
 int main()
 {
-    /* Set the console baud-rate */
-    output.baud(115200);
-    printf("\r\nmbed OS version is %d.\r\n", MBED_VERSION);
+    SocketAddress ip_addr;
+    SocketAddress ip_mask;
+    SocketAddress ip_gwaddr;
+    
+#ifdef MBED_MAJOR_VERSION
+    printf("Mbed OS version %d.%d.%d\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
+#endif
     printf("Start Serial-to-Ethernet...\r\n");
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
 
     /* Restore configuration from SD card */
     
-    SD_Card_Mounted = (fs.mount(&bd) >= 0);
+    printf("Mounting SD card...\r\n");
+    SD_Card_Mounted = (fs.mount(bd) == 0);
     if (SD_Card_Mounted)
     {
+        printf("SD card mounted. Read configuration file...\r\n");
         FILE *fd = fopen(SER_CONFIG_FILE, "r");
         if (fd != NULL)
         {
@@ -276,6 +312,7 @@
 
 #endif
     
+    /* Configure serial ports */
     printf("Configure UART ports...\r\n");
     for(int i=0; i<MAX_UART_PORTS; i++)
     {
@@ -283,21 +320,27 @@
         port_config[i].pserial->format(port_config[i].data, port_config[i].parity, port_config[i].stop);
     }
     
+    /* Configure network IP address */
     if (net_config.mode == IP_STATIC_MODE)
     {
         printf("Start Ethernet in Static mode.\r\n");
         eth.disconnect();
-        ((NetworkInterface *)&eth)->set_network(net_config.ip, net_config.mask, net_config.gateway);
+        
+        ip_addr.set_ip_address(net_config.ip);
+        ip_mask.set_ip_address(net_config.mask);
+        ip_gwaddr.set_ip_address(net_config.gateway);
+        ((NetworkInterface *)&eth)->set_network(ip_addr, ip_mask, ip_gwaddr);
     }
     else
         printf("Start Ethernet in DHCP mode.\r\n");
     
     eth.connect();
-    printf("IP Address is %s\r\n", eth.get_ip_address());
-    
+    eth.get_ip_address(&ip_addr);
+    printf("IP Address is %s\r\n", ip_addr.get_ip_address());
+
     Thread thread[MAX_UART_PORTS];
     
-    // Folk thread for each port
+    /* Folk thread for each serial port */  
     for(int i=0; i<MAX_UART_PORTS; i++)
     {
         if (port_config[i].mode == NET_SERVER_MODE)
@@ -310,7 +353,7 @@
         }
     }
 
-#ifdef ENABLE_WEB_CONFIG
+#if ENABLE_WEB_CONFIG
     
     /*** main thread to be a web server for configuration ***/
     start_httpd();