Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- morgandu
- Date:
- 2019-03-22
- Revision:
- 6:dc9f344f4bf0
- Parent:
- 5:7e7ad7c079fe
- Child:
- 7:cbb5a2a2a0d2
File content as of revision 6:dc9f344f4bf0:
/*
* 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.
// 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 */
S_NET_CONFIG net_config = {IP_STATIC_MODE, IP_ADDRESS, NETWORK_MASK, GATEWAY_ADDRESS};
#if defined (TARGET_NUMAKER_PFM_M487) || defined(TARGET_NUMAKER_IOT_M487)
BufferedSerial serial_0(PB_3, PB_2, 256, 4); // UART1
BufferedSerial serial_1(PA_5, PA_4, 256, 4); // UART5
//BufferedSerial serial_2(PB_13, PB_12, 256, 4); // UART0, Debug
#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) || defined(TARGET_NUMAKER_PFM_NANO130)
#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, UART0 on NuMaker-PFM-M487
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;
unsigned int eth_tx_count = 0;
while(1)
{
/*** Network to Serial ***/
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 == 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);
break;
}
}
else
{
n_index += pmap->pserial->write(n_buf+n_index, n_len-n_index);
if (n_index == n_len)
{
n_len = 0;
n_index = 0;
}
}
/*** Serial to Network ***/
// try to get more data from serial port
for(; s_index < sizeof(s_buf) && pmap->pserial->readable(); s_index++)
s_buf[s_index] = pmap->pserial->getc();
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)
{
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;
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)
{
printf("\r\nConnected.");
break;
}
}
socket.set_timeout(1);
exchange_data(pmap, &socket);
socket.close();
}
void bridge_net_server(S_PORT_CONFIG *pmap)
{
TCPSocket 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;
}
while(1)
{
client_socket = tcp_server.accept(&err);
if (err < 0) // && err != NSAPI_ERROR_WOULD_BLOCK)
{
printf("TCP server fail to accept connection (%d)(%x).\r\n", err, (unsigned int)pmap);
return;
}
else
{
client_socket->getpeername(&client_address);
printf("Connect (%d) from %s:%d ...\r\n", pmap->port, client_address.get_ip_address(), client_address.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);
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();
}