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 Sep 30 21:18:05 2014 +0000
Revision:
15:edeb0aed160d
Parent:
14:18eda020a589
Child:
16:84a5bf7285d0
Added auto update function using TCP client mode

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