rs485 to ethernet
Dependencies: BufferedSerialttt
Fork of Serial-to-Ethernet by
Diff: main.cpp
- Revision:
- 0:11bc39d0f367
- Child:
- 1:c53f82eb6b42
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri May 05 07:40:19 2017 +0000 @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2017 Nuvoton Tecnology Corp. All rights reserved. + * + * The code is forward data from UART port to Ethernet, and vice versa. + * + * + */ + +#include "ste_config.h" + +/* If define USE_STATIC_IP, specify the default IP address. */ +#if 0 + // private IP address for general purpose +#define IP_ADDRESS "192.168.1.2" +#define NETWORK_MASK "255.255.255.0" +#define GATEWAY_ADDRESS "192.168.1.1" +#else + // private IP address only for test with Windows when DHCP server doesn't exist. +#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 */ +S_NET_CONFIG net_config = {IP_STATIC_MODE, IP_ADDRESS, NETWORK_MASK, GATEWAY_ADDRESS}; + +#if defined (TARGET_NUMAKER_PFM_M487) +#error Not defined UART ports yet. + +#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 + +#elif defined (TARGET_NUMAKER_PFM_M453) +#error The board has no Ethernet. + +#else +#error define UART ports for your board. +#endif + +/* Default configuration for network ports and UART ports, etc. */ +S_PORT_CONFIG port_config[MAX_UART_PORTS] = { + +#if MAX_UART_PORTS == 1 + {NET_SERVER_MODE, NET_PORT_BASE, &serial_0, DEFAULT_UART_BAUD, 8, 1, SerialBase::None} + +#elif MAX_UART_PORTS == 2 + {NET_SERVER_MODE, NET_PORT_BASE + 0, &serial_0, DEFAULT_UART_BAUD, 8, 1, SerialBase::None}, + {NET_SERVER_MODE, NET_PORT_BASE + 1, &serial_1, DEFAULT_UART_BAUD, 8, 1, SerialBase::None} + +#elif MAX_UART_PORTS == 3 + {NET_SERVER_MODE, NET_PORT_BASE + 0, &serial_0, DEFAULT_UART_BAUD, 8, 1, SerialBase::None}, + {NET_SERVER_MODE, NET_PORT_BASE + 1, &serial_1, DEFAULT_UART_BAUD, 8, 1, SerialBase::None}, + {NET_SERVER_MODE, NET_PORT_BASE + 2, &serial_2, DEFAULT_UART_BAUD, 8, 1, SerialBase::None} + +#else +#error You have to define ports mapping table. +#endif +}; + +/* UART port to output debug message */ +RawSerial output(USBTX, USBRX); // UART3 on NuMaker-PFM-NUC472 +EthernetInterface eth; + +#ifdef ENABLE_WEB_CONFIG + +/* Declare the SD card as storage */ +NuSDBlockDevice bd; +FATFileSystem fs("fs"); +bool SD_Card_Mounted = FALSE; + +#endif + +/* --- --- */ + +/* + * Forward serial port data to ethernet, and vice versa. + * + */ +void exchange_data(S_PORT_CONFIG *pmap, TCPSocket *psocket) +{ + unsigned char n_buf[256]; + unsigned char s_buf[256]; + int n_len = 0, n_index = 0; + int s_len = 0, s_index = 0; + + while(1) + { + /*** Network to Serial ***/ + + if (n_len < 0 || n_len == n_index) + { + // 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) + { + } + 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++) + { + pmap->pserial->putc(n_buf[n_index]); + } + } + + /*** Serial to Network ***/ + + 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 = 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; + } + } + } + } +} + +void bridge_net_client(S_PORT_CONFIG *pmap) +{ + TCPSocket socket; + SocketAddress server_address; + nsapi_error_t err; + + printf("Thread %x in TCP client mode.\r\n", (unsigned int)pmap); + + if ((err=socket.open(ð)) < 0) + { + printf("TCP socket can't open (%d)(%x).\r\n", err, (unsigned int)pmap); + return; + } + + 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) + break; + } + + printf("\r\nConnected."); + + socket.set_timeout(1); + exchange_data(pmap, &socket); +} + +void bridge_net_server(S_PORT_CONFIG *pmap) +{ + TCPServer tcp_server; + TCPSocket client_socket; + SocketAddress client_address; + nsapi_error_t err; + + printf("Thread %x in TCP server mode.\r\n", (unsigned int)pmap); + + if ((err=tcp_server.open(ð)) < 0) + { + 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) + { + printf("TCP server can't bind address and port (%d)(%x).\r\n", err, (unsigned int)pmap); + return; + } + if ((err=tcp_server.listen(1)) < 0) + { + printf("TCP server can't listen (%d)(%x).\r\n", err, (unsigned int)pmap); + return; + } + + client_socket.set_timeout(1); + + while(1) + { + if ((err=tcp_server.accept(&client_socket, &client_address)) < 0) + { + 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); + } +} + +int main() +{ + /* Set the console baud-rate */ + output.baud(115200); + printf("\r\nmbed OS version is %d.\r\n", MBED_VERSION); + printf("Start Serial-to-Ethernet...\r\n"); + +#ifdef ENABLE_WEB_CONFIG + + /* Restore configuration from SD card */ + + SD_Card_Mounted = (fs.mount(&bd) >= 0); + if (SD_Card_Mounted) + { + FILE *fd = fopen(SER_CONFIG_FILE, "r"); + if (fd != NULL) + { + char pBuf[sizeof(port_config)+2]; + int len = fread(pBuf, 1, sizeof(port_config)+2, fd); + if (len == (sizeof(port_config)+2) && pBuf[0] == 'N' && pBuf[1] == 'T') + { + printf("Set Serial ports from config file in SD card.\r\n"); + memcpy(port_config, pBuf+2, sizeof(port_config)); + } + else + printf("Incorrect serial config file.\r\n"); + + fclose(fd); + } + else + printf("Can't open serial config file.\r\n"); + + fd = fopen(NET_CONFIG_FILE, "r"); + if (fd != NULL) + { + char pBuf[sizeof(net_config)+2]; + int len = fread(pBuf, 1, sizeof(net_config)+2, fd); + if (len == (sizeof(net_config)+2) && pBuf[0] == 'N' && pBuf[1] == 'T') + { + printf("Set network from config file in SD card.\r\n"); + memcpy(&net_config, pBuf+2, sizeof(net_config)); + } + else + printf("Incorrect network config file.\r\n"); + + fclose(fd); + } + else + printf("Can't open network config file.\r\n"); + } + else + { + printf("Can't find SD card.\r\n"); + } + +#endif + + printf("Configure UART ports...\r\n"); + for(int i=0; i<MAX_UART_PORTS; i++) + { + port_config[i].pserial->baud(port_config[i].baud); + port_config[i].pserial->format(port_config[i].data, port_config[i].parity, port_config[i].stop); + } + + if (net_config.mode == IP_STATIC_MODE) + { + printf("Start Ethernet in Static mode.\r\n"); + eth.disconnect(); + ((NetworkInterface *)ð)->set_network(net_config.ip, net_config.mask, net_config.gateway); + } + else + printf("Start Ethernet in DHCP mode.\r\n"); + + eth.connect(); + printf("IP Address is %s\r\n", eth.get_ip_address()); + + Thread thread[MAX_UART_PORTS]; + + // Folk thread for each port + for(int i=0; i<MAX_UART_PORTS; i++) + { + if (port_config[i].mode == NET_SERVER_MODE) + { + thread[i].start(callback(bridge_net_server, &(port_config[i]))); + } + else // if (port_config[i].mode == TCP_CLIENT_MODE) + { + thread[i].start(callback(bridge_net_client, &(port_config[i]))); + } + } + +#ifdef ENABLE_WEB_CONFIG + + /*** main thread to be a web server for configuration ***/ + start_httpd(); + +#endif + + while(1); + + /* end of main task */ + //eth.disconnect(); +}