Webserver only w/o any other functions, single thread. Running on STM32F013+W5500

Dependencies:   NTPClient W5500Interface Watchdog device_configuration eeprom_flash mbed-rpc-nucleo mbed-rtos mbed

Fork of F103-Serial-to-Ethernet by Chau Vo

Committer:
olympux
Date:
Tue Oct 21 20:39:15 2014 +0000
Revision:
18:ca499a2e7da6
Parent:
17:88ef7a078095
Child:
19:05934ee9ee67
Added flags for tcp server and client but not in use.; Updated debug strings.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
olympux 0:c2eac797face 1 /*
olympux 0:c2eac797face 2 *
olympux 2:18f10e7209f4 3 * Alarm and Monitoring application
olympux 0:c2eac797face 4
olympux 0:c2eac797face 5 */
olympux 0:c2eac797face 6 #include "mbed.h"
olympux 12:7c152c0ca4d8 7 #include "eeprom.h"
olympux 0:c2eac797face 8 #include "EthernetInterface.h"
olympux 9:d2534ecf88c6 9 #include "NTPClient.h"
olympux 0:c2eac797face 10 #include "rtos.h"
olympux 0:c2eac797face 11
olympux 12:7c152c0ca4d8 12 #include "my_eeprom_funcs.h"
olympux 12:7c152c0ca4d8 13
olympux 0:c2eac797face 14
olympux 16:84a5bf7285d0 15 //Debug is disabled by default
olympux 16:84a5bf7285d0 16 #if 1
olympux 16:84a5bf7285d0 17 //Enable debug
olympux 16:84a5bf7285d0 18 #include <cstdio>
olympux 16:84a5bf7285d0 19 #define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__);
olympux 16:84a5bf7285d0 20 #define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__);
olympux 16:84a5bf7285d0 21 #define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__);
olympux 16:84a5bf7285d0 22
olympux 16:84a5bf7285d0 23 #else
olympux 16:84a5bf7285d0 24 //Disable debug
olympux 16:84a5bf7285d0 25 #define DBG(x, ...)
olympux 16:84a5bf7285d0 26 #define WARN(x, ...)
olympux 16:84a5bf7285d0 27 #define ERR(x, ...)
olympux 16:84a5bf7285d0 28
olympux 16:84a5bf7285d0 29 #endif
olympux 16:84a5bf7285d0 30
olympux 16:84a5bf7285d0 31
olympux 2:18f10e7209f4 32 /*
olympux 2:18f10e7209f4 33 * Hardware defines
olympux 0:c2eac797face 34 */
olympux 2:18f10e7209f4 35 #define ST_NUCLEO // hardware pin mapping
olympux 0:c2eac797face 36
olympux 0:c2eac797face 37 #ifdef ST_NUCLEO
olympux 9:d2534ecf88c6 38 // Ethernet
olympux 0:c2eac797face 39 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
olympux 11:709f90a3b599 40 EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset
olympux 0:c2eac797face 41 #endif
olympux 0:c2eac797face 42
olympux 9:d2534ecf88c6 43 // Serial
olympux 2:18f10e7209f4 44 Serial uart(USBTX,USBRX);
olympux 2:18f10e7209f4 45
olympux 9:d2534ecf88c6 46 // Digital inputs
olympux 11:709f90a3b599 47 DigitalIn din0(PB_14);
olympux 11:709f90a3b599 48 DigitalIn din1(PB_12);
olympux 11:709f90a3b599 49 DigitalIn din2(PB_10);
olympux 11:709f90a3b599 50 DigitalIn din3(PB_1);
olympux 11:709f90a3b599 51 DigitalIn din4(PB_15);
olympux 11:709f90a3b599 52 DigitalIn din5(PB_13);
olympux 11:709f90a3b599 53 DigitalIn din6(PB_11);
olympux 11:709f90a3b599 54 DigitalIn din7(PB_2);
olympux 9:d2534ecf88c6 55 // Digital outputs
olympux 11:709f90a3b599 56 DigitalOut dout0(PB_3);
olympux 11:709f90a3b599 57 DigitalOut dout1(PB_5);
olympux 11:709f90a3b599 58 DigitalOut dout2(PB_7);
olympux 11:709f90a3b599 59 DigitalOut dout3(PB_9);
olympux 11:709f90a3b599 60 DigitalOut dout4(PD_2);
olympux 11:709f90a3b599 61 DigitalOut dout5(PB_4);
olympux 11:709f90a3b599 62 DigitalOut dout6(PB_6);
olympux 11:709f90a3b599 63 DigitalOut dout7(PB_8);
olympux 9:d2534ecf88c6 64 // Analog inputs
olympux 11:709f90a3b599 65 AnalogIn ain0(PC_0);
olympux 11:709f90a3b599 66 AnalogIn ain1(PC_1);
olympux 9:d2534ecf88c6 67 // Analog outputs
olympux 11:709f90a3b599 68 //AnalogOut ano0(PA_8);
olympux 11:709f90a3b599 69 //AnalogOut ano1(PA_15);
olympux 11:709f90a3b599 70
olympux 12:7c152c0ca4d8 71 void update_digital_outputs(char* buf);
olympux 12:7c152c0ca4d8 72 void update_sending_frame(char* buf);
olympux 11:709f90a3b599 73
olympux 9:d2534ecf88c6 74
olympux 9:d2534ecf88c6 75
olympux 13:bcf840da68fd 76 /*
olympux 13:bcf840da68fd 77 * EEPROM section
olympux 13:bcf840da68fd 78 */
olympux 6:d054e394fba3 79 // Virtual address defined by the user: 0xFFFF value is prohibited
olympux 6:d054e394fba3 80 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
olympux 6:d054e394fba3 81 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
olympux 6:d054e394fba3 82 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
olympux 6:d054e394fba3 83 0x4212, // TCP server port, not used
olympux 8:64848959adb9 84 0x5212, // UDP server port, not used
olympux 16:84a5bf7285d0 85 0x8888, // 1st run? 0xA5A5 = configured
olympux 12:7c152c0ca4d8 86 0x6212, 0x6313, 0x6414, // MAC
olympux 12:7c152c0ca4d8 87
olympux 12:7c152c0ca4d8 88 // this section is for the TCP server that this device connects to in TCP client mode
olympux 16:84a5bf7285d0 89 0x7212, 0x7313, // 0xA5 = auto transmit status, time period
olympux 12:7c152c0ca4d8 90 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
olympux 16:84a5bf7285d0 91 0x9212, // TCP server port
olympux 16:84a5bf7285d0 92
olympux 16:84a5bf7285d0 93 // this section is for selecting protocol
olympux 16:84a5bf7285d0 94 0xA212, // 0xA5A5 = enable TCP server
olympux 16:84a5bf7285d0 95 0xA313, // 0xA5A5 = eanble TCP client
olympux 18:ca499a2e7da6 96 0xA414 // 0xA5A5 = enable UDP server
olympux 6:d054e394fba3 97 };
olympux 0:c2eac797face 98
olympux 2:18f10e7209f4 99 /*
olympux 2:18f10e7209f4 100 * Network configuration
olympux 2:18f10e7209f4 101 */
olympux 4:568c97f2a407 102 #define TCP_SERVER
olympux 15:edeb0aed160d 103 #define TCP_CLIENT
olympux 4:568c97f2a407 104 #define UDP_SERVER
olympux 4:568c97f2a407 105 //#define UDP_CLIENT
olympux 10:4cd965d79de0 106 #define NTP
olympux 4:568c97f2a407 107
olympux 4:568c97f2a407 108 #define TCP_SERVER_WAIT_CLIENT_TIMEOUT 200
olympux 4:568c97f2a407 109 #define TCP_SERVER_RECEIVE_TIMEOUT 3000
olympux 4:568c97f2a407 110 #define UDP_SERVER_RECEIVE_TIMEOUT 200
olympux 4:568c97f2a407 111
olympux 15:edeb0aed160d 112
olympux 15:edeb0aed160d 113 // TCP server function
olympux 15:edeb0aed160d 114 TCPSocketServer tcp_server;
olympux 15:edeb0aed160d 115 TCPSocketConnection tcp_client;
olympux 15:edeb0aed160d 116 // TCP client function
olympux 15:edeb0aed160d 117 TCPSocketConnection tcp_sock;
olympux 15:edeb0aed160d 118 // UDP server
olympux 15:edeb0aed160d 119 UDPSocket udp_server;
olympux 15:edeb0aed160d 120 Endpoint ep_udp_client;
olympux 15:edeb0aed160d 121 // NTP
olympux 13:bcf840da68fd 122 NTPClient ntp;
olympux 13:bcf840da68fd 123
olympux 13:bcf840da68fd 124
olympux 15:edeb0aed160d 125
olympux 13:bcf840da68fd 126 /*
olympux 13:bcf840da68fd 127 * Variables for network configuration, server
olympux 13:bcf840da68fd 128 */
olympux 11:709f90a3b599 129 uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits
olympux 11:709f90a3b599 130 uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom
olympux 11:709f90a3b599 131 char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx
olympux 9:d2534ecf88c6 132 uint16_t first_run = 0; // first run flag
olympux 9:d2534ecf88c6 133
olympux 12:7c152c0ca4d8 134 const uint16_t tcp_server_local_port = 10000; // fixed
olympux 12:7c152c0ca4d8 135 const uint16_t udp_server_local_port = 11000; // fixed
olympux 12:7c152c0ca4d8 136
olympux 12:7c152c0ca4d8 137 // TCP client: this section is used for the TCP server that this device connects to in TCP client mode
olympux 12:7c152c0ca4d8 138 // this device will transmit status every transmit_time_period
olympux 12:7c152c0ca4d8 139 uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
olympux 12:7c152c0ca4d8 140 uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
olympux 14:18eda020a589 141 uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
olympux 14:18eda020a589 142 char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
olympux 12:7c152c0ca4d8 143 uint16_t u16tcp_server_port; // directly loaded from eeprom
olympux 18:ca499a2e7da6 144 uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
olympux 12:7c152c0ca4d8 145
olympux 15:edeb0aed160d 146 char tcp_client_buffer[256]; // socket buffer
olympux 15:edeb0aed160d 147 char udp_server_buffer[256];
olympux 15:edeb0aed160d 148 char tcp_server_buffer[256];
olympux 12:7c152c0ca4d8 149
olympux 0:c2eac797face 150
olympux 13:bcf840da68fd 151 /*
olympux 13:bcf840da68fd 152 * Protocol
olympux 13:bcf840da68fd 153 */
olympux 9:d2534ecf88c6 154 // Commands
olympux 17:88ef7a078095 155 #define DEVICE_ID "NNIO"
olympux 17:88ef7a078095 156
olympux 17:88ef7a078095 157 #define RECEIVING_PROTOCOL_LENGTH 58
olympux 17:88ef7a078095 158 #define SENDING_PROTOCOL_LENGTH 39
olympux 17:88ef7a078095 159 #define QUERY_CMD_LENGTH 6
olympux 17:88ef7a078095 160 #define SET_NETWORK_CONFIG_CMD_LENGTH 19
olympux 17:88ef7a078095 161 #define UPDATE_TCP_SERVER_INFO_CMD_LENGTH 12
olympux 17:88ef7a078095 162
olympux 17:88ef7a078095 163 #define QUERY_DISCOVERY_CMD "NNIODS"
olympux 17:88ef7a078095 164 #define QUERY_IP_CMD "NNIOIP"
olympux 17:88ef7a078095 165 #define QUERY_SUBNET_CMD "NNIOSN"
olympux 17:88ef7a078095 166 #define QUERY_GATEWAY_CMD "NNIOGW"
olympux 17:88ef7a078095 167 #define QUERY_MAC_CMD "NNIOMC"
olympux 17:88ef7a078095 168 #define QUERY_UDP_PORT_CMD "NNIOUP"
olympux 17:88ef7a078095 169 #define QUERY_TCP_PORT_CMD "NNIOTP"
olympux 17:88ef7a078095 170 #define QUERY_UPDATE_TIME_CMD "NNIOTM"
olympux 11:709f90a3b599 171 #define RECEIVING_PROTOCOL_ENABLE_OUTPUT 'O'
olympux 11:709f90a3b599 172 #define QUERY_STATUS_COMMAND 'Q'
olympux 11:709f90a3b599 173 #define DIGITAL_HIGH 'H'
olympux 11:709f90a3b599 174 #define DIGITAL_LOW 'L'
olympux 9:d2534ecf88c6 175
olympux 9:d2534ecf88c6 176
olympux 9:d2534ecf88c6 177 // Positions
olympux 11:709f90a3b599 178 #define RECEIVING_PROTOCOL_ID_POS 0
olympux 9:d2534ecf88c6 179 #define RECEIVING_PROTOCOL_OP_POS 4
olympux 9:d2534ecf88c6 180 #define RECEIVING_PROTOCOL_EN_DO_POS RECEIVING_PROTOCOL_OP_POS + 0
olympux 9:d2534ecf88c6 181 #define RECEIVING_PROTOCOL_EN_A0O_POS RECEIVING_PROTOCOL_OP_POS + 1
olympux 9:d2534ecf88c6 182 #define RECEIVING_PROTOCOL_EN_A1O_POS RECEIVING_PROTOCOL_OP_POS + 2
olympux 9:d2534ecf88c6 183 #define RECEIVING_PROTOCOL_EN_UART_POS RECEIVING_PROTOCOL_OP_POS + 3
olympux 9:d2534ecf88c6 184 #define RECEIVING_PROTOCOL_COMMAND_POS RECEIVING_PROTOCOL_OP_POS + 4
olympux 11:709f90a3b599 185
olympux 11:709f90a3b599 186 #define RECEIVING_PROTOCOL_IP_POS 9
olympux 11:709f90a3b599 187 #define RECEIVING_PROTOCOL_DO_POS 13
olympux 11:709f90a3b599 188 #define RECEIVING_PROTOCOL_A0O_POS 21
olympux 11:709f90a3b599 189 #define RECEIVING_PROTOCOL_A01_POS 23
olympux 11:709f90a3b599 190 #define RECEIVING_PROTOCOL_UART_POS 25
olympux 9:d2534ecf88c6 191
olympux 9:d2534ecf88c6 192
olympux 11:709f90a3b599 193 #define SENDING_PROTOCOL_ID_POS 0
olympux 11:709f90a3b599 194 #define SENDING_PROTOCOL_MAC_POS 4
olympux 11:709f90a3b599 195 #define SENDING_PROTOCOL_IP_POS 10
olympux 11:709f90a3b599 196 #define SENDING_PROTOCOL_DI_POS 14
olympux 11:709f90a3b599 197 #define SENDING_PROTOCOL_DO_POS 22
olympux 11:709f90a3b599 198 #define SENDING_PROTOCOL_AI0_POS 30
olympux 11:709f90a3b599 199 #define SENDING_PROTOCOL_AI1_POS 32
olympux 11:709f90a3b599 200 #define SENDING_PROTOCOL_AO0_POS 34
olympux 11:709f90a3b599 201 #define SENDING_PROTOCOL_AO1_POS 36
olympux 11:709f90a3b599 202 #define SENDING_PROTOCOL_CR_POS 38
olympux 0:c2eac797face 203
olympux 2:18f10e7209f4 204
olympux 2:18f10e7209f4 205 /*
olympux 2:18f10e7209f4 206 * RTOS
olympux 2:18f10e7209f4 207 */
olympux 2:18f10e7209f4 208 struct message_t {
olympux 2:18f10e7209f4 209 int len;
olympux 2:18f10e7209f4 210 char *msg;
olympux 2:18f10e7209f4 211 };
olympux 3:972ed747474c 212 Queue<message_t, 16> uart_queue;
olympux 15:edeb0aed160d 213 Queue<bool, 1> auto_update_queue;
olympux 2:18f10e7209f4 214
olympux 3:972ed747474c 215 Mutex uart_mutex;
olympux 2:18f10e7209f4 216
olympux 2:18f10e7209f4 217
olympux 2:18f10e7209f4 218 /*
olympux 2:18f10e7209f4 219 * Threads
olympux 2:18f10e7209f4 220 */
olympux 0:c2eac797face 221 void uart_thread(void const *args) {
olympux 2:18f10e7209f4 222 message_t *p_message;
olympux 0:c2eac797face 223
olympux 0:c2eac797face 224 while (true) {
olympux 3:972ed747474c 225 osEvent evt = uart_queue.get();
olympux 2:18f10e7209f4 226 if (evt.status == osEventMessage) {
olympux 2:18f10e7209f4 227 p_message = (message_t*)evt.value.p;
olympux 11:709f90a3b599 228 uart_mutex.lock(); // mutex for stdio is not neccessary
olympux 16:84a5bf7285d0 229 //DBG("len=%d\n", p_message->len);
olympux 16:84a5bf7285d0 230 DBG("%s\n", p_message->msg);
olympux 3:972ed747474c 231 uart_mutex.unlock();
olympux 2:18f10e7209f4 232 }
olympux 0:c2eac797face 233 }
olympux 0:c2eac797face 234 }
olympux 0:c2eac797face 235
olympux 0:c2eac797face 236
olympux 15:edeb0aed160d 237 // Timer thread for auto update
olympux 15:edeb0aed160d 238 void auto_update_timer_thread(void const* args) {
olympux 18:ca499a2e7da6 239 bool update_flag = true;
olympux 15:edeb0aed160d 240
olympux 15:edeb0aed160d 241 Thread::wait(500);
olympux 15:edeb0aed160d 242 while(true) {
olympux 15:edeb0aed160d 243 auto_update_queue.put(&update_flag);
olympux 18:ca499a2e7da6 244 Thread::wait(1000*transmit_time_period); // Thread::wait() in ms
olympux 15:edeb0aed160d 245 }
olympux 15:edeb0aed160d 246 }
olympux 15:edeb0aed160d 247
olympux 15:edeb0aed160d 248
olympux 6:d054e394fba3 249 /*
olympux 6:d054e394fba3 250 * Ethernet init
olympux 6:d054e394fba3 251 */
olympux 4:568c97f2a407 252 int ethernet_init(void) {
olympux 18:ca499a2e7da6 253 DBG("Start initialising ethernet");
olympux 14:18eda020a589 254 int ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 0:c2eac797face 255
olympux 0:c2eac797face 256 if (!ret) {
olympux 18:ca499a2e7da6 257 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 0:c2eac797face 258 } else {
olympux 18:ca499a2e7da6 259 ERR("Error eth.init() - ret = %d", ret);
olympux 0:c2eac797face 260 return -1;
olympux 0:c2eac797face 261 }
olympux 0:c2eac797face 262
olympux 0:c2eac797face 263 ret = eth.connect();
olympux 0:c2eac797face 264 if (!ret) {
olympux 18:ca499a2e7da6 265 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 0:c2eac797face 266 } else {
olympux 18:ca499a2e7da6 267 ERR("Error eth.connect() - ret = %d", ret);
olympux 0:c2eac797face 268 return -1;
olympux 0:c2eac797face 269 }
olympux 3:972ed747474c 270
olympux 4:568c97f2a407 271 return 0;
olympux 4:568c97f2a407 272 }
olympux 4:568c97f2a407 273
olympux 4:568c97f2a407 274
olympux 6:d054e394fba3 275
olympux 6:d054e394fba3 276
olympux 4:568c97f2a407 277
olympux 4:568c97f2a407 278 int main()
olympux 4:568c97f2a407 279 {
olympux 4:568c97f2a407 280 message_t message;
olympux 9:d2534ecf88c6 281 int n, ret;
olympux 4:568c97f2a407 282
olympux 15:edeb0aed160d 283 Thread::wait(2000); // turn on delay
olympux 15:edeb0aed160d 284
olympux 4:568c97f2a407 285 /*
olympux 9:d2534ecf88c6 286 * Configure
olympux 4:568c97f2a407 287 */
olympux 11:709f90a3b599 288 uart.baud(115200);
olympux 18:ca499a2e7da6 289 DBG("\r\nStarting...");
olympux 4:568c97f2a407 290
olympux 4:568c97f2a407 291 /*
olympux 4:568c97f2a407 292 * UI threads
olympux 4:568c97f2a407 293 */
olympux 4:568c97f2a407 294 Thread t1(uart_thread);
olympux 18:ca499a2e7da6 295 Thread t2(auto_update_timer_thread);
olympux 6:d054e394fba3 296
olympux 6:d054e394fba3 297 /*
olympux 6:d054e394fba3 298 * FLASH
olympux 6:d054e394fba3 299 */
olympux 12:7c152c0ca4d8 300 load_eeprom_network();
olympux 15:edeb0aed160d 301 load_eeprom_tcpserver();
olympux 4:568c97f2a407 302
olympux 4:568c97f2a407 303 /*
olympux 4:568c97f2a407 304 * Ethernet
olympux 4:568c97f2a407 305 */
olympux 6:d054e394fba3 306 ret = ethernet_init();
olympux 4:568c97f2a407 307 if (ret) {
olympux 18:ca499a2e7da6 308 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 309 while (true) {};
olympux 4:568c97f2a407 310 }
olympux 4:568c97f2a407 311
olympux 12:7c152c0ca4d8 312
olympux 12:7c152c0ca4d8 313 /*
olympux 12:7c152c0ca4d8 314 * TCP/UDP setup
olympux 12:7c152c0ca4d8 315 */
olympux 3:972ed747474c 316 #ifdef TCP_SERVER
olympux 12:7c152c0ca4d8 317 tcp_server.bind(tcp_server_local_port);
olympux 3:972ed747474c 318 tcp_server.listen();
olympux 18:ca499a2e7da6 319 DBG("TCP server started...");
olympux 4:568c97f2a407 320 tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
olympux 3:972ed747474c 321 #endif
olympux 14:18eda020a589 322
olympux 14:18eda020a589 323 #ifdef TCP_CLIENT
olympux 18:ca499a2e7da6 324
olympux 14:18eda020a589 325 #endif
olympux 3:972ed747474c 326
olympux 3:972ed747474c 327 #ifdef UDP_SERVER
olympux 12:7c152c0ca4d8 328 ret = udp_server.bind(udp_server_local_port);
olympux 18:ca499a2e7da6 329 DBG("UDP started (sock.bind = %d)", ret);
olympux 4:568c97f2a407 330 udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
olympux 3:972ed747474c 331 #endif
olympux 3:972ed747474c 332
olympux 3:972ed747474c 333
olympux 12:7c152c0ca4d8 334 /*
olympux 12:7c152c0ca4d8 335 * Network processor
olympux 12:7c152c0ca4d8 336 */
olympux 0:c2eac797face 337 while (true) {
olympux 15:edeb0aed160d 338 #ifdef TCP_CLIENT
olympux 18:ca499a2e7da6 339 // FOR AUTO TRANSMIT DEVICE STATUS
olympux 18:ca499a2e7da6 340 //if ((u16enable_tcp_client == 0xA5A5) && (auto_transmit_flag == 0xA5A5)) {
olympux 18:ca499a2e7da6 341 if (auto_transmit_flag == 0xA5A5) {
olympux 18:ca499a2e7da6 342 // connect to TCP server if required
olympux 18:ca499a2e7da6 343 if (!tcp_sock.is_connected()) {
olympux 18:ca499a2e7da6 344 ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port);
olympux 18:ca499a2e7da6 345 if (ret > -1) {
olympux 18:ca499a2e7da6 346 DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port);
olympux 18:ca499a2e7da6 347 }
olympux 18:ca499a2e7da6 348 else {
olympux 18:ca499a2e7da6 349 ERR("Unable to connect to %s on port %d", str_server_ip_addr, u16tcp_server_port);
olympux 18:ca499a2e7da6 350 }
olympux 16:84a5bf7285d0 351 }
olympux 18:ca499a2e7da6 352
olympux 18:ca499a2e7da6 353 // transmit data if connected
olympux 18:ca499a2e7da6 354 if (tcp_sock.is_connected()) {
olympux 18:ca499a2e7da6 355 osEvent evt = auto_update_queue.get(1); // timeout after 1ms
olympux 18:ca499a2e7da6 356 if (evt.status == osEventMessage) {
olympux 18:ca499a2e7da6 357 DBG("Updating...");
olympux 18:ca499a2e7da6 358 update_sending_frame(tcp_client_buffer);
olympux 18:ca499a2e7da6 359 tcp_sock.send_all(tcp_client_buffer, SENDING_PROTOCOL_LENGTH);
olympux 18:ca499a2e7da6 360 }
olympux 16:84a5bf7285d0 361 }
olympux 18:ca499a2e7da6 362 } // if tcp client enabled && auto transmit
olympux 15:edeb0aed160d 363 #endif
olympux 15:edeb0aed160d 364
olympux 15:edeb0aed160d 365
olympux 9:d2534ecf88c6 366 // FOR INTERFACING
olympux 4:568c97f2a407 367 #ifdef TCP_SERVER
olympux 4:568c97f2a407 368 // no tcp client connected
olympux 18:ca499a2e7da6 369 //if ((u16enable_tcp_server == 0xA5A5) && (!tcp_client.is_connected())) {
olympux 18:ca499a2e7da6 370 if (!tcp_client.is_connected()) {
olympux 4:568c97f2a407 371 // wait for client within timeout
olympux 4:568c97f2a407 372 ret = tcp_server.accept(tcp_client);
olympux 2:18f10e7209f4 373
olympux 4:568c97f2a407 374 // tcp client connected
olympux 4:568c97f2a407 375 if (ret > -1) {
olympux 18:ca499a2e7da6 376 DBG("Connection from: %s", tcp_client.get_address());
olympux 4:568c97f2a407 377
olympux 4:568c97f2a407 378 // loop waiting and receiving data within timeout
olympux 4:568c97f2a407 379 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
olympux 4:568c97f2a407 380 while (true) {
olympux 15:edeb0aed160d 381 n = tcp_client.receive(tcp_server_buffer, sizeof(tcp_server_buffer));
olympux 4:568c97f2a407 382 if (n <= 0) break;
olympux 4:568c97f2a407 383
olympux 9:d2534ecf88c6 384 // got some data, test it
olympux 18:ca499a2e7da6 385 DBG("TCP server received: %s", tcp_server_buffer);
olympux 9:d2534ecf88c6 386 // process received data
olympux 9:d2534ecf88c6 387 switch (n) {
olympux 9:d2534ecf88c6 388 // length 58-bytes, Receiving protocol
olympux 11:709f90a3b599 389 case RECEIVING_PROTOCOL_LENGTH: {
olympux 16:84a5bf7285d0 390 DBG("Checking device ID...");
olympux 9:d2534ecf88c6 391 // check device id
olympux 15:edeb0aed160d 392 char* id = strstr(tcp_server_buffer, DEVICE_ID);
olympux 9:d2534ecf88c6 393 if (id == NULL)
olympux 9:d2534ecf88c6 394 break;
olympux 15:edeb0aed160d 395 else if ((id - tcp_server_buffer) > 0)
olympux 9:d2534ecf88c6 396 break;
olympux 18:ca499a2e7da6 397 DBG("Correct.");
olympux 9:d2534ecf88c6 398
olympux 9:d2534ecf88c6 399 // firstly, update outputs if required
olympux 9:d2534ecf88c6 400 // digital outputs
olympux 15:edeb0aed160d 401 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 18:ca499a2e7da6 402 DBG("Update digital outputs");
olympux 12:7c152c0ca4d8 403 char str_dout[9];
olympux 15:edeb0aed160d 404 memcpy(str_dout, &tcp_server_buffer[RECEIVING_PROTOCOL_DO_POS], 8);
olympux 12:7c152c0ca4d8 405 str_dout[8] = '\0';
olympux 12:7c152c0ca4d8 406 update_digital_outputs(str_dout);
olympux 9:d2534ecf88c6 407 }
olympux 9:d2534ecf88c6 408 // analog output 0
olympux 15:edeb0aed160d 409 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 18:ca499a2e7da6 410 DBG("Update analog output 0");
olympux 9:d2534ecf88c6 411 }
olympux 11:709f90a3b599 412 // analog output 1
olympux 15:edeb0aed160d 413 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 18:ca499a2e7da6 414 DBG("Update analog output 1");
olympux 9:d2534ecf88c6 415 }
olympux 9:d2534ecf88c6 416 // UART
olympux 15:edeb0aed160d 417 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 16:84a5bf7285d0 418 DBG("UART data: ");
olympux 11:709f90a3b599 419 char str_uart[33];
olympux 15:edeb0aed160d 420 memcpy(str_uart, &tcp_server_buffer[RECEIVING_PROTOCOL_UART_POS], 32);
olympux 11:709f90a3b599 421 str_uart[32] = '\0';
olympux 11:709f90a3b599 422 printf("%s\r\n", str_uart);
olympux 9:d2534ecf88c6 423 }
olympux 9:d2534ecf88c6 424
olympux 9:d2534ecf88c6 425 // then, check query status command and sending protocol if required
olympux 15:edeb0aed160d 426 if (tcp_server_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
olympux 18:ca499a2e7da6 427 DBG("Sent device status through TCP");
olympux 9:d2534ecf88c6 428 // sending protocol
olympux 15:edeb0aed160d 429 update_sending_frame(tcp_server_buffer);
olympux 15:edeb0aed160d 430 tcp_client.send_all(tcp_server_buffer, SENDING_PROTOCOL_LENGTH);
olympux 9:d2534ecf88c6 431 }
olympux 9:d2534ecf88c6 432
olympux 9:d2534ecf88c6 433 break;
olympux 9:d2534ecf88c6 434 }
olympux 9:d2534ecf88c6 435 default:
olympux 9:d2534ecf88c6 436 break;
olympux 9:d2534ecf88c6 437 }
olympux 4:568c97f2a407 438 } // end loop if no data received within timeout
olympux 4:568c97f2a407 439 tcp_client.close();
olympux 4:568c97f2a407 440 } // if client connected
olympux 18:ca499a2e7da6 441 } // if tcp server enabled && no client connected
olympux 3:972ed747474c 442 #endif
olympux 3:972ed747474c 443
olympux 9:d2534ecf88c6 444
olympux 9:d2534ecf88c6 445
olympux 18:ca499a2e7da6 446 // ALWAYS ENABLED, ONLY FOR CONFIGRATION
olympux 9:d2534ecf88c6 447 #ifdef UDP_SERVER
olympux 4:568c97f2a407 448 // wait for udp packet within timeout
olympux 15:edeb0aed160d 449 n = udp_server.receiveFrom(ep_udp_client, udp_server_buffer, sizeof(udp_server_buffer));
olympux 9:d2534ecf88c6 450 if (n <= 0) continue;
olympux 3:972ed747474c 451
olympux 9:d2534ecf88c6 452 // got some data, test it
olympux 18:ca499a2e7da6 453 DBG("UDP received (%s) from (%s) and port (%d)", udp_server_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
olympux 6:d054e394fba3 454 // process received data
olympux 6:d054e394fba3 455 switch (n) {
olympux 17:88ef7a078095 456 // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
olympux 17:88ef7a078095 457 // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
olympux 17:88ef7a078095 458 case QUERY_CMD_LENGTH:
olympux 7:d45bd480e90f 459 // discovery command
olympux 17:88ef7a078095 460 if (strstr(udp_server_buffer, QUERY_DISCOVERY_CMD) != NULL) {
olympux 17:88ef7a078095 461 char str[30];
olympux 17:88ef7a078095 462 sprintf(str, "%s%s", DEVICE_ID, eth.getIPAddress());
olympux 17:88ef7a078095 463 udp_server.sendTo(ep_udp_client, str, strlen(str));
olympux 10:4cd965d79de0 464 } // NNIODS
olympux 17:88ef7a078095 465 else if (strstr(udp_server_buffer, QUERY_IP_CMD) != NULL) {
olympux 17:88ef7a078095 466 udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
olympux 17:88ef7a078095 467 } // NNIOIP
olympux 17:88ef7a078095 468 else if (strstr(udp_server_buffer, QUERY_SUBNET_CMD) != NULL) {
olympux 17:88ef7a078095 469 udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
olympux 17:88ef7a078095 470 } // NNIOSN
olympux 17:88ef7a078095 471 else if (strstr(udp_server_buffer, QUERY_GATEWAY_CMD) != NULL) {
olympux 17:88ef7a078095 472 udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
olympux 17:88ef7a078095 473 } // NNIOGW
olympux 17:88ef7a078095 474 else if (strstr(udp_server_buffer, QUERY_MAC_CMD) != NULL) {
olympux 17:88ef7a078095 475 udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
olympux 17:88ef7a078095 476 } // NNIOMC
olympux 7:d45bd480e90f 477 // ask for TCP server port
olympux 17:88ef7a078095 478 else if (strstr(udp_server_buffer, QUERY_TCP_PORT_CMD) != NULL) {
olympux 7:d45bd480e90f 479 char port[5];
olympux 12:7c152c0ca4d8 480 sprintf(port, "%5d", tcp_server_local_port);
olympux 7:d45bd480e90f 481 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 10:4cd965d79de0 482 } // NNIOTP
olympux 7:d45bd480e90f 483 // ask for UDP server port
olympux 17:88ef7a078095 484 else if (strstr(udp_server_buffer, QUERY_UDP_PORT_CMD) != NULL) {
olympux 7:d45bd480e90f 485 char port[5];
olympux 12:7c152c0ca4d8 486 sprintf(port, "%5d", udp_server_local_port);
olympux 7:d45bd480e90f 487 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 10:4cd965d79de0 488 } // NNIOUP
olympux 17:88ef7a078095 489 else if (strstr(udp_server_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
olympux 10:4cd965d79de0 490 #ifdef NTP
olympux 10:4cd965d79de0 491 char str_time[50];
olympux 10:4cd965d79de0 492
olympux 18:ca499a2e7da6 493 DBG("Trying to update time...");
olympux 10:4cd965d79de0 494 if (ntp.setTime("0.pool.ntp.org") == 0) {
olympux 18:ca499a2e7da6 495 DBG("Set time successfully");
olympux 10:4cd965d79de0 496 time_t ctTime;
olympux 10:4cd965d79de0 497 ctTime = time(NULL);
olympux 10:4cd965d79de0 498
olympux 18:ca499a2e7da6 499 DBG("Time is set to (UTC): %s", ctime(&ctTime));
olympux 10:4cd965d79de0 500 sprintf(str_time, "%s", ctime(&ctTime));
olympux 10:4cd965d79de0 501 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 502 }
olympux 10:4cd965d79de0 503 else {
olympux 18:ca499a2e7da6 504 WARN("Error");
olympux 10:4cd965d79de0 505 sprintf(str_time, "ERR");
olympux 10:4cd965d79de0 506 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 507 }
olympux 10:4cd965d79de0 508 #elif
olympux 18:ca499a2e7da6 509 WARN("NTP disabled");
olympux 10:4cd965d79de0 510 sprintf(str_time, "DIS");
olympux 10:4cd965d79de0 511 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 512 #endif
olympux 10:4cd965d79de0 513 } // NNIOTM
olympux 10:4cd965d79de0 514
olympux 7:d45bd480e90f 515 break;
olympux 9:d2534ecf88c6 516 // length = 19, SET NETWORK CONFIGURATION
olympux 9:d2534ecf88c6 517 // Format: 4E 4E 49 4F C0 A8 00 78 FF FF FF 00 C0 A8 00 01 00 00 01
olympux 9:d2534ecf88c6 518 // (NNIO; IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
olympux 17:88ef7a078095 519 case SET_NETWORK_CONFIG_CMD_LENGTH: {
olympux 9:d2534ecf88c6 520 // check device id
olympux 15:edeb0aed160d 521 char* id = strstr(udp_server_buffer, DEVICE_ID);
olympux 9:d2534ecf88c6 522 if (id == NULL)
olympux 9:d2534ecf88c6 523 break;
olympux 15:edeb0aed160d 524 else if ((id - udp_server_buffer) > 0)
olympux 9:d2534ecf88c6 525 break;
olympux 9:d2534ecf88c6 526
olympux 18:ca499a2e7da6 527 DBG("Received user configuration");
olympux 15:edeb0aed160d 528 write_eeprom_network(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
olympux 15:edeb0aed160d 529 break;
olympux 15:edeb0aed160d 530 }
olympux 15:edeb0aed160d 531 // length = 12, SET TCP SERVER CONFIGURATION
olympux 15:edeb0aed160d 532 // auto update & its time period, TCP server configuration (IP & port)
olympux 17:88ef7a078095 533 // Format: 4E 4E 49 4F 'Y' 01 C0 A8 00 09 E0 2E (LSB MSB)
olympux 15:edeb0aed160d 534 // NNIO Auto 1s 192.168.0.9 12000
olympux 17:88ef7a078095 535 case UPDATE_TCP_SERVER_INFO_CMD_LENGTH: {
olympux 15:edeb0aed160d 536 char* id = strstr(udp_server_buffer, DEVICE_ID);
olympux 15:edeb0aed160d 537 if (id == NULL)
olympux 15:edeb0aed160d 538 break;
olympux 15:edeb0aed160d 539 else if ((id - udp_server_buffer) > 0)
olympux 15:edeb0aed160d 540 break;
olympux 15:edeb0aed160d 541
olympux 18:ca499a2e7da6 542 DBG("Received TCP server configuration");
olympux 15:edeb0aed160d 543 write_eeprom_tcpserver(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
olympux 6:d054e394fba3 544 break;
olympux 9:d2534ecf88c6 545 }
olympux 6:d054e394fba3 546 default:
olympux 6:d054e394fba3 547 break;
olympux 4:568c97f2a407 548 }
olympux 3:972ed747474c 549 #endif
olympux 4:568c97f2a407 550 } // network processor
olympux 11:709f90a3b599 551 }
olympux 11:709f90a3b599 552
olympux 12:7c152c0ca4d8 553 /*
olympux 12:7c152c0ca4d8 554 * Update digital outputs following receiving frame from TCP client
olympux 12:7c152c0ca4d8 555 */
olympux 12:7c152c0ca4d8 556 void update_digital_outputs(char* buf) {
olympux 18:ca499a2e7da6 557 DBG("Digital outputs: %s", buf);
olympux 11:709f90a3b599 558
olympux 12:7c152c0ca4d8 559 dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 560 dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 561 dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 562 dout3 = (buf[3] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 563 dout4 = (buf[4] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 564 dout5 = (buf[5] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 565 dout6 = (buf[6] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 566 dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 567 }
olympux 12:7c152c0ca4d8 568
olympux 12:7c152c0ca4d8 569 void update_sending_frame(char* buf) {
olympux 12:7c152c0ca4d8 570 memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_ID, 4); // device id
olympux 12:7c152c0ca4d8 571 memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
olympux 12:7c152c0ca4d8 572 memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4);
olympux 11:709f90a3b599 573
olympux 12:7c152c0ca4d8 574 buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 575 buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 576 buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 577 buf[SENDING_PROTOCOL_DI_POS+3] = (din3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 578 buf[SENDING_PROTOCOL_DI_POS+4] = (din4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 579 buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 580 buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 581 buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 582
olympux 12:7c152c0ca4d8 583 buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 584 buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 585 buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 586 buf[SENDING_PROTOCOL_DO_POS+3] = (dout3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 587 buf[SENDING_PROTOCOL_DO_POS+4] = (dout4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 588 buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 589 buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 590 buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 591
olympux 15:edeb0aed160d 592 uint16_t val = ain0.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 593 memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 594 val = ain1.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 595 memcpy(&buf[SENDING_PROTOCOL_AI1_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 596 val = 0x0180;
olympux 15:edeb0aed160d 597 memcpy(&buf[SENDING_PROTOCOL_AO0_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 598 val = 0x0180;
olympux 15:edeb0aed160d 599 memcpy(&buf[SENDING_PROTOCOL_AO1_POS], &val, 2); // LSB MSB
olympux 12:7c152c0ca4d8 600 buf[SENDING_PROTOCOL_CR_POS] = 0x0D;
olympux 12:7c152c0ca4d8 601 buf[SENDING_PROTOCOL_CR_POS+1] = '\0';
olympux 4:568c97f2a407 602 }