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.
Dependencies: NTPClient W5500Interface Watchdog device_configuration eeprom_flash mbed-rpc-nucleo mbed-rtos mbed
Fork of F103-Serial-to-Ethernet by
main.cpp
- Committer:
- olympux
- Date:
- 2014-12-29
- Revision:
- 28:00c0c20d03c1
- Parent:
- 27:22f289beceb8
- Child:
- 29:bc052f283ada
File content as of revision 28:00c0c20d03c1:
/*
*
* Alarm and Monitoring application
*/
#include "mbed.h"
#include "rtos.h"
#include "mbed_rpc.h"
#include "Arguments.h"
#include "eeprom.h"
#include "EthernetInterface.h"
#include "NTPClient.h"
#include "my_eeprom_funcs.h"
#include "Watchdog.h"
//Debug is disabled by default
#if 1
//Enable debug
#include <cstdio>
#define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__);
#define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__);
#define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__);
#else
//Disable debug
#define DBG(x, ...)
#define WARN(x, ...)
#define ERR(x, ...)
#endif
/*
* Hardware defines
*/
#define ST_NUCLEO // hardware pin mapping
#ifdef ST_NUCLEO
// Ethernet
SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset
#endif
//Use the RPC enabled wrapped class - see RpcClasses.h for more info
// DigitalIn
RpcDigitalIn di0(PB_14, "din0");
RpcDigitalIn di1(PB_12, "din1");
RpcDigitalIn di2(PB_10, "din2");
RpcDigitalIn di3(PB_1, "din3");
RpcDigitalIn di4(PB_15, "din4");
RpcDigitalIn di5(PB_13, "din5");
RpcDigitalIn di6(PB_11, "din6");
RpcDigitalIn di7(PB_2, "din7");
DigitalIn din0(PB_14);
DigitalIn din1(PB_12);
DigitalIn din2(PB_10);
DigitalIn din3(PB_1);
DigitalIn din4(PB_15);
DigitalIn din5(PB_13);
DigitalIn din6(PB_11);
DigitalIn din7(PB_2);
// DigitalOut
RpcDigitalOut do0(PB_3, "dout0");
RpcDigitalOut do1(PB_5, "dout1");
RpcDigitalOut do2(PB_7, "dout2");
RpcDigitalOut do3(PB_9, "dout3");
RpcDigitalOut do4(PD_2, "dout4");
RpcDigitalOut do5(PB_4, "dout5");
RpcDigitalOut do6(PB_6, "dout6");
RpcDigitalOut do7(PB_8, "dout7");
DigitalOut dout0(PB_3);
DigitalOut dout1(PB_5);
DigitalOut dout2(PB_7);
DigitalOut dout3(PB_9);
DigitalOut dout4(PD_2);
DigitalOut dout5(PB_4);
DigitalOut dout6(PB_6);
DigitalOut dout7(PB_8);
// AnalogIn
RpcAnalogIn adc10(PC_0, "ain0"); // adc10
RpcAnalogIn adc11(PC_1, "ain1"); // adc11
AnalogIn ain0(PC_0);
AnalogIn ain1(PC_1);
// AnalogOut, PWM
RpcPwmOut pwm11(PA_8, "pwm0"); // pwm11
RpcPwmOut pwm21(PA_15, "pwm1"); // pwm21
// Serial
RpcSerial usart2(USBTX, USBRX, "uart"); // usart2
Serial uart(USBTX,USBRX);
// Timer
RpcTimer timer1("timer1");
// Watchdog
Watchdog wdt;
/*
* EEPROM section
*/
// Virtual address defined by the user: 0xFFFF value is prohibited
uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
0x4212, // TCP server port, not used
0x5212, // UDP server port, not used
0x8888, // 1st run? 0xA5A5 = configured
0x6212, 0x6313, 0x6414, // MAC
// this section is for the TCP server that this device connects to in TCP client mode
0x7212, 0x7313, // 0xA5 = auto transmit status, time period
0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
0x9212, // TCP server port
// this section is for selecting protocol
0xA212, // 0xA5A5 = enable TCP server
0xA313, // 0xA5A5 = eanble TCP client
0xA414 // 0xA5A5 = enable UDP server
};
/*
* Network configuration
*/
#define TCP_SERVER
#define TCP_CLIENT
#define UDP_SERVER
//#define UDP_CLIENT
#define NTP
#define TCP_SERVER_WAIT_CLIENT_TIMEOUT 200 // timeout for local tcp server wait for a remote client
#define TCP_SERVER_RECEIVE_TIMEOUT 2000 // timeout for local tcp server wait to receive from remote client
#define TCP_CLIENT_RECEIVE_TIMEOUT 200 // timeout for local tcp client try to connect remote server
#define UDP_SERVER_RECEIVE_TIMEOUT 100 // timeout for checking config command
// TCP server function
TCPSocketServer tcp_server;
TCPSocketConnection tcp_client;
// TCP client function
TCPSocketConnection tcp_sock;
// UDP server
UDPSocket udp_server;
Endpoint ep_udp_client;
// NTP
NTPClient ntp;
/*
* Variables for network configuration, server
*/
uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits
uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom
char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx
uint16_t configured_ip = 0; // static ip configured flag
const uint16_t tcp_server_local_port = 10000; // fixed, change to 7000 if internet required
const uint16_t udp_server_local_port = 11000; // fixed
// TCP client: this section is used for the TCP server that this device connects to in TCP client mode
// this device will transmit status every transmit_time_period
uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
uint16_t u16tcp_server_port; // directly loaded from eeprom
uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
char tcp_receiving_buffer[256];
char tcp_sending_buffer[256]; // socket buffer
char udp_receiving_buffer[256];
char rpc_outbuf[256]; // rpc output buffer
/*
* Protocol
*/
// Commands
#define DEVICE_CONFIG_CODE "NNCF"
#define DEVICE_CONTROL_CODE "NNIO"
#define RECEIVING_PROTOCOL_LENGTH 58
#define SENDING_PROTOCOL_LENGTH 39
#define QUERY_NETWORK_CONFIG_CMD_LENGTH 6
#define SET_NETWORK_CONFIG_CMD_LENGTH 19
#define UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH 12
#define QUERY_DISCOVERY_CMD "NNCFDS"
#define QUERY_IP_CMD "NNCFIP"
#define QUERY_SUBNET_CMD "NNCFSN"
#define QUERY_GATEWAY_CMD "NNCFGW"
#define QUERY_MAC_CMD "NNCFMC"
#define QUERY_UDP_PORT_CMD "NNCFUP"
#define QUERY_TCP_PORT_CMD "NNCFTP"
#define QUERY_UPDATE_TIME_CMD "NNCFTM"
#define RECEIVING_PROTOCOL_ENABLE_OUTPUT 'O'
#define QUERY_STATUS_COMMAND 'Q'
#define DIGITAL_HIGH 'H'
#define DIGITAL_LOW 'L'
// Positions
#define RECEIVING_PROTOCOL_ID_POS 0
#define RECEIVING_PROTOCOL_OP_POS 4
#define RECEIVING_PROTOCOL_EN_DO_POS RECEIVING_PROTOCOL_OP_POS + 0
#define RECEIVING_PROTOCOL_EN_A0O_POS RECEIVING_PROTOCOL_OP_POS + 1
#define RECEIVING_PROTOCOL_EN_A1O_POS RECEIVING_PROTOCOL_OP_POS + 2
#define RECEIVING_PROTOCOL_EN_UART_POS RECEIVING_PROTOCOL_OP_POS + 3
#define RECEIVING_PROTOCOL_COMMAND_POS RECEIVING_PROTOCOL_OP_POS + 4
#define RECEIVING_PROTOCOL_IP_POS 9
#define RECEIVING_PROTOCOL_DO_POS 13
#define RECEIVING_PROTOCOL_A0O_POS 21
#define RECEIVING_PROTOCOL_A01_POS 23
#define RECEIVING_PROTOCOL_UART_POS 25
#define SENDING_PROTOCOL_ID_POS 0
#define SENDING_PROTOCOL_MAC_POS 4
#define SENDING_PROTOCOL_IP_POS 10
#define SENDING_PROTOCOL_DI_POS 14
#define SENDING_PROTOCOL_DO_POS 22
#define SENDING_PROTOCOL_AI0_POS 30
#define SENDING_PROTOCOL_AI1_POS 32
#define SENDING_PROTOCOL_AO0_POS 34
#define SENDING_PROTOCOL_AO1_POS 36
#define SENDING_PROTOCOL_CR_POS 38
/*
* RTOS
*/
struct message_t {
int len;
char *msg;
};
Queue<message_t, 16> uart_queue;
Queue<bool, 1> auto_update_queue;
// Prototypes
int ethernet_init(void);
int process_control_command(char* received_buffer, int len);
void process_config_command(char* received_buffer, int len);
void update_digital_outputs(char* buf);
void update_sending_frame(char* buf);
/*
* Threads
*/
// Timer thread for auto update
void auto_update_timer_thread(void const* args) {
bool update_flag = true;
Thread::wait(500);
while(true) {
auto_update_queue.put(&update_flag);
Thread::wait(1000*transmit_time_period); // Thread::wait() in ms
}
}
// WDT reset
void wdt_reset_thread(void const* args) {
while (true)
wdt.Service();
}
int main()
{
int n, ret;
Thread::wait(500); // turn on delay
/*
* Configure
*/
uart.baud(115200);
DBG("\r\nStarting...");
if (wdt.WatchdogCausedReset())
DBG("Watchdog caused reset.");
wdt.Configure(4);
/*
* FLASH
*/
load_eeprom_network();
load_eeprom_tcpserver();
/*
* UI threads
*/
Thread t2(auto_update_timer_thread);
Thread t3(wdt_reset_thread);
/*
* Ethernet
*/
ret = ethernet_init();
if (ret) {
ERR("Ethernet initialisation failed. App halted.");
while (true) {};
}
Thread::wait(2000); // TCP/UDP stack delay
/*
* UDP server
* TCP server/client
*/
#ifdef UDP_SERVER
ret = udp_server.bind(udp_server_local_port);
DBG("UDP server started (sock.bind = %d)...", ret);
udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
#endif
#ifdef TCP_SERVER
tcp_server.bind(tcp_server_local_port);
tcp_server.listen();
DBG("TCP server started...");
tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
#endif
#ifdef TCP_CLIENT
#endif
/*
* Network loop processor
*/
while (true) {
#ifdef TCP_CLIENT
// FOR AUTO TRANSMIT DEVICE STATUS
//if ((u16enable_tcp_client == 0xA5A5) && (auto_transmit_flag == 0xA5A5)) {
if (auto_transmit_flag == 0xA5A5) {
// connect to TCP server if required
if (!tcp_sock.is_connected()) {
ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port); // timeout is default in connect() in W5500.h
if (ret > -1) {
DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port);
}
else {
ERR("Unable to connect to %s on port %d", str_server_ip_addr, u16tcp_server_port);
}
}
// transmit data if connected
if (tcp_sock.is_connected()) {
osEvent evt = auto_update_queue.get(1); // timeout after 1ms
if (evt.status == osEventMessage) {
DBG("Updating...");
update_sending_frame(tcp_sending_buffer);
tcp_sock.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
}
// check to receive or timeout
tcp_sock.set_blocking(false, TCP_CLIENT_RECEIVE_TIMEOUT);
n = tcp_sock.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
if (n > 0) {
// got some data, test it
DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer);
process_control_command(tcp_receiving_buffer, n);
}
}
} // if tcp client enabled && auto transmit
#endif
// FOR INTERFACING
#ifdef TCP_SERVER
// no tcp client connected
//if ((u16enable_tcp_server == 0xA5A5) && (!tcp_client.is_connected())) {
//if (!tcp_client.is_connected()) {
if (1) {
// wait for client within timeout
ret = tcp_server.accept(tcp_client);
// tcp client connected
if (ret > -1) {
DBG("Connection from: %s", tcp_client.get_address());
// loop waiting and receiving data within timeout
tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
while (true) {
n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
if (n <= 0) break;
// got some data, process it
tcp_receiving_buffer[n] = '\0'; // for debugging purpose
DBG("TCP server received: %s", tcp_receiving_buffer);
n = process_control_command(tcp_receiving_buffer, n);
// send rpc reply back to client, NNIO protocol always returns 0
if (n > 0) {
tcp_client.send_all(rpc_outbuf, strlen(rpc_outbuf));
}
} // end loop if no data received within timeout
} // if client connected
tcp_client.close();
} // if tcp server enabled && no client connected
#endif
#ifdef UDP_SERVER
bool discovery_mode_flag, config_mode_flag;
n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
// check to see if it is a query command
// if yes, is it a discovery command or an ip query to enter config mode
discovery_mode_flag = false;
config_mode_flag = false;
if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
discovery_mode_flag = true;
DBG("Received discovery command");
char str[50];
sprintf(str, "%s%s%s", DEVICE_CONFIG_CODE, eth.getMACAddress(), eth.getIPAddress());
udp_server.sendTo(ep_udp_client, str, strlen(str));
} // NNCFDS
else if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
config_mode_flag = true;
DBG("Entered configuration mode...");
DBG("!!! RESET when finished");
} // NNCFIP
// if received NNCFIP, enter config mode
if (config_mode_flag) {
while (n > 0)
{
// got some data, test it
DBG("UDP received (%s) from (%s:%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
process_config_command(udp_receiving_buffer, n);
// wait to receive new config command
udp_server.set_blocking(true);
n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
} // while (n > 0), config loop
} // if (config_mode_flag)
else if ((n > 0) && (!discovery_mode_flag)) { // process control packages sent using UDP
n = process_control_command(udp_receiving_buffer, n);
// send rpc reply back to client, NNIO protocol always returns 0
if (n > 0) {
udp_server.sendTo(ep_udp_client, rpc_outbuf, strlen(rpc_outbuf));
}
}
#endif
} // network processor
}
/*
* Process NNCF commands
*/
void process_config_command(char* received_buffer, int len)
{
DBG("Processing configuration command");
// process received data
// a configuration command always starts with NN
if ((received_buffer[0] == 'N') && (received_buffer[1] == 'N') &&
(received_buffer[2] == 'C') && (received_buffer[3] == 'F')) {
switch (len) {
// length = 6, a QUERY command (discovery command, TCP port, or UDP port)
// Format: NNCFDS, NNCFTP, NNCFUP, NNCFTM
case QUERY_NETWORK_CONFIG_CMD_LENGTH:
if (strstr(received_buffer, QUERY_IP_CMD) != NULL) {
udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
} // NNCFIP
else if (strstr(received_buffer, QUERY_SUBNET_CMD) != NULL) {
udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
} // NNCFSN
else if (strstr(received_buffer, QUERY_GATEWAY_CMD) != NULL) {
udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
} // NNCFGW
else if (strstr(received_buffer, QUERY_MAC_CMD) != NULL) {
udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
} // NNCFMC
// ask for TCP server port
else if (strstr(received_buffer, QUERY_TCP_PORT_CMD) != NULL) {
char port[5];
sprintf(port, "%5d", tcp_server_local_port);
udp_server.sendTo(ep_udp_client, port, strlen(port));
} // NNCFTP
// ask for UDP server port
else if (strstr(received_buffer, QUERY_UDP_PORT_CMD) != NULL) {
char port[5];
sprintf(port, "%5d", udp_server_local_port);
udp_server.sendTo(ep_udp_client, port, strlen(port));
} // NNCFUP
else if (strstr(received_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
#ifdef NTP
char str_time[50];
DBG("Trying to update time...");
if (ntp.setTime("0.pool.ntp.org") == 0) {
DBG("Set time successfully");
time_t ctTime;
ctTime = time(NULL);
DBG("Time is set to (UTC): %s", ctime(&ctTime));
sprintf(str_time, "%s", ctime(&ctTime));
udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
} else {
WARN("Error");
sprintf(str_time, "ERR");
udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
}
#elif
WARN("NTP disabled");
sprintf(str_time, "DIS");
udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
#endif
} // NNCFTM
break;
// length = 19, SET NETWORK CONFIGURATION
// Format: 4E 4E 43 46 C0 A8 00 78 FF FF FF 00 C0 A8 00 01 00 00 01
// (NNCF; IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
case SET_NETWORK_CONFIG_CMD_LENGTH: {
// check device id
char* id = strstr(received_buffer, DEVICE_CONFIG_CODE);
if (id == NULL)
break;
else if ((id - received_buffer) > 0)
break;
DBG("Received user configuration");
write_eeprom_network(&received_buffer[strlen(DEVICE_CONFIG_CODE)]); // parameters from 5th char, 15-bytes
break;
}
// length = 12, SET TCP SERVER CONFIGURATION
// auto update & its time period, TCP server configuration (IP & port)
// Format: 4E 4E 43 46 'Y' 01 C0 A8 00 09 E0 2E (LSB MSB)
// NNCF Auto 1s 192.168.0.9 12000
case UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH: {
char* id = strstr(received_buffer, DEVICE_CONFIG_CODE);
if (id == NULL)
break;
else if ((id - received_buffer) > 0)
break;
DBG("Received TCP server configuration");
write_eeprom_tcpserver(&received_buffer[strlen(DEVICE_CONFIG_CODE)]); // parameters from 5th char
break;
}
default:
break;
} // switch (n), check configuration command length
} // if starts with NNCF, a config command
else { // if not a command, check to see if it is a 6-byte data package
// process 6-byte data package
}
}
/*
* Procedure to process receiving protocol, which includes command to control outputs
* Return: 0 if NNIO protocol; length of rpc output buffer if rpc; -1 if rpc failed
*/
int process_control_command(char* received_buffer, int len)
{
char* received_frame;
int pos;
char inbuf[256];
DBG("Processing control command");
// check RPC protocol
strncpy(inbuf, received_buffer, len);
inbuf[len] = '\r'; // use inbuf for RPC protocol
inbuf[len+1] = '\n';
inbuf[len+2] = '\0'; // add CR-LF
if ((len > 0) && (inbuf[0] == '/')) {
bool result;
DBG("Rpc command = %s", inbuf);
result = RPC::call(inbuf, rpc_outbuf);
if (result) {
// calculate length of rpc_outbuf
int i = strlen(rpc_outbuf);
DBG("Rpc reply (%d bytes): %s", i, rpc_outbuf);
return i; // return length of rpc_outbuf
}
else {
ERR("Failed: %s", inbuf);
return -1;
}
}
/*
* This section below is for NNIO protocol
*/
while (len >= RECEIVING_PROTOCOL_LENGTH) {
// find device ID
DBG("Checking device ID...");
char* id = strstr(received_buffer, DEVICE_CONTROL_CODE);
if (id == NULL) {
DBG("No device ID found");
break;
}
pos = id - received_buffer;
DBG("Found a frame at %d", pos);
// extract this frame
received_frame = &received_buffer[pos];
// calculate the rest
received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH];
len -= RECEIVING_PROTOCOL_LENGTH;
// process this received frame
// firstly, update outputs if required
// digital outputs
if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
DBG("Update digital outputs");
char str_dout[9];
memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8);
str_dout[8] = '\0';
update_digital_outputs(str_dout);
}
// analog output 0
if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
DBG("Update analog output 0");
//TODO Update analog output
}
// analog output 1
if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
DBG("Update analog output 1");
//TODO Update analog output
}
// UART
if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
DBG("UART data: ");
char str_uart[33];
memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32);
str_uart[32] = '\0';
uart.printf("%s\r\n", str_uart);
}
// then, check query status command and sending protocol if required
if (received_frame[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
DBG("Requested to send device status through TCP");
// sending protocol
update_sending_frame(tcp_sending_buffer);
tcp_client.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
DBG("Sent");
}
}
DBG("Successfully processed.");
return 0;
}
/*
* W5500 Ethernet init
*/
int ethernet_init(void) {
int dhcp_ret, ret;
DBG("Initialising ethernet...");
// if not configured, try dhcp
dhcp_ret = -1;
if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
DBG("Connecting to DHCP server...");
dhcp_ret = eth.init(u8mac);
if (dhcp_ret == 0)
dhcp_ret = eth.connect();
}
if (dhcp_ret != 0) {
DBG("No DHCP, load static IP configuration");
ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
} else {
snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
ret = 0;
}
if (ret == 0) {
DBG("Initialized, MAC: %s", eth.getMACAddress());
} else {
ERR("Error eth.init() - ret = %d", ret);
return -1;
}
ret = eth.connect();
if (!ret) {
DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
} else {
ERR("Error eth.connect() - ret = %d", ret);
return -1;
}
return 0;
}
/*
* Update digital outputs according to receiving protocol
*/
void update_digital_outputs(char* buf) {
DBG("Digital outputs: %s", buf);
dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0;
dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0;
dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0;
dout3 = (buf[3] == DIGITAL_HIGH)? 1 : 0;
dout4 = (buf[4] == DIGITAL_HIGH)? 1 : 0;
dout5 = (buf[5] == DIGITAL_HIGH)? 1 : 0;
dout6 = (buf[6] == DIGITAL_HIGH)? 1 : 0;
dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
}
/*
* Prepare a frame for sending protocol, which includes status of I/Os
*/
void update_sending_frame(char* buf) {
memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_CONTROL_CODE, 4); // device id
memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4);
buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+3] = (din3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+4] = (din4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+3] = (dout3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+4] = (dout4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
uint16_t val = ain0.read_u16(); // 16-bits normalised
memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB
val = ain1.read_u16(); // 16-bits normalised
memcpy(&buf[SENDING_PROTOCOL_AI1_POS], &val, 2); // LSB MSB
val = 0x1234;
memcpy(&buf[SENDING_PROTOCOL_AO0_POS], &val, 2); // LSB MSB
val = 0x5678;
memcpy(&buf[SENDING_PROTOCOL_AO1_POS], &val, 2); // LSB MSB
buf[SENDING_PROTOCOL_CR_POS] = 0x0D;
buf[SENDING_PROTOCOL_CR_POS+1] = '\0';
}
