Chau Vo / Mbed 2 deprecated F103-Web-Server

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:
Thu Oct 02 19:41:38 2014 +0000
Revision:
16:84a5bf7285d0
Parent:
15:edeb0aed160d
Child:
17:88ef7a078095
Added DBG.; Checked auto transmit flag.

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 16:84a5bf7285d0 96 0xA414 // 0xA5A5 = enable UDP client
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 12:7c152c0ca4d8 144
olympux 15:edeb0aed160d 145 char tcp_client_buffer[256]; // socket buffer
olympux 15:edeb0aed160d 146 char udp_server_buffer[256];
olympux 15:edeb0aed160d 147 char tcp_server_buffer[256];
olympux 12:7c152c0ca4d8 148
olympux 0:c2eac797face 149
olympux 13:bcf840da68fd 150 /*
olympux 13:bcf840da68fd 151 * Protocol
olympux 13:bcf840da68fd 152 */
olympux 9:d2534ecf88c6 153 // Commands
olympux 9:d2534ecf88c6 154 #define DEVICE_ID "NNIO"
olympux 9:d2534ecf88c6 155 #define DISCOVERY_COMMAND "NNIODS"
olympux 9:d2534ecf88c6 156 #define TCP_SERVER_PORT_COMAMND "NNIOTP"
olympux 9:d2534ecf88c6 157 #define UDP_SERVER_PORT_COMAMND "NNIOUP"
olympux 11:709f90a3b599 158 #define RECEIVING_PROTOCOL_ENABLE_OUTPUT 'O'
olympux 11:709f90a3b599 159 #define QUERY_STATUS_COMMAND 'Q'
olympux 11:709f90a3b599 160 #define DIGITAL_HIGH 'H'
olympux 11:709f90a3b599 161 #define DIGITAL_LOW 'L'
olympux 9:d2534ecf88c6 162
olympux 9:d2534ecf88c6 163
olympux 9:d2534ecf88c6 164 // Positions
olympux 11:709f90a3b599 165 #define RECEIVING_PROTOCOL_LENGTH 58
olympux 11:709f90a3b599 166 #define RECEIVING_PROTOCOL_ID_POS 0
olympux 9:d2534ecf88c6 167 #define RECEIVING_PROTOCOL_OP_POS 4
olympux 9:d2534ecf88c6 168 #define RECEIVING_PROTOCOL_EN_DO_POS RECEIVING_PROTOCOL_OP_POS + 0
olympux 9:d2534ecf88c6 169 #define RECEIVING_PROTOCOL_EN_A0O_POS RECEIVING_PROTOCOL_OP_POS + 1
olympux 9:d2534ecf88c6 170 #define RECEIVING_PROTOCOL_EN_A1O_POS RECEIVING_PROTOCOL_OP_POS + 2
olympux 9:d2534ecf88c6 171 #define RECEIVING_PROTOCOL_EN_UART_POS RECEIVING_PROTOCOL_OP_POS + 3
olympux 9:d2534ecf88c6 172 #define RECEIVING_PROTOCOL_COMMAND_POS RECEIVING_PROTOCOL_OP_POS + 4
olympux 11:709f90a3b599 173
olympux 11:709f90a3b599 174 #define RECEIVING_PROTOCOL_IP_POS 9
olympux 11:709f90a3b599 175 #define RECEIVING_PROTOCOL_DO_POS 13
olympux 11:709f90a3b599 176 #define RECEIVING_PROTOCOL_A0O_POS 21
olympux 11:709f90a3b599 177 #define RECEIVING_PROTOCOL_A01_POS 23
olympux 11:709f90a3b599 178 #define RECEIVING_PROTOCOL_UART_POS 25
olympux 9:d2534ecf88c6 179
olympux 9:d2534ecf88c6 180
olympux 11:709f90a3b599 181 #define SENDING_PROTOCOL_LENGTH 39
olympux 11:709f90a3b599 182 #define SENDING_PROTOCOL_ID_POS 0
olympux 11:709f90a3b599 183 #define SENDING_PROTOCOL_MAC_POS 4
olympux 11:709f90a3b599 184 #define SENDING_PROTOCOL_IP_POS 10
olympux 11:709f90a3b599 185 #define SENDING_PROTOCOL_DI_POS 14
olympux 11:709f90a3b599 186 #define SENDING_PROTOCOL_DO_POS 22
olympux 11:709f90a3b599 187 #define SENDING_PROTOCOL_AI0_POS 30
olympux 11:709f90a3b599 188 #define SENDING_PROTOCOL_AI1_POS 32
olympux 11:709f90a3b599 189 #define SENDING_PROTOCOL_AO0_POS 34
olympux 11:709f90a3b599 190 #define SENDING_PROTOCOL_AO1_POS 36
olympux 11:709f90a3b599 191 #define SENDING_PROTOCOL_CR_POS 38
olympux 0:c2eac797face 192
olympux 2:18f10e7209f4 193
olympux 2:18f10e7209f4 194 /*
olympux 2:18f10e7209f4 195 * RTOS
olympux 2:18f10e7209f4 196 */
olympux 2:18f10e7209f4 197 struct message_t {
olympux 2:18f10e7209f4 198 int len;
olympux 2:18f10e7209f4 199 char *msg;
olympux 2:18f10e7209f4 200 };
olympux 3:972ed747474c 201 Queue<message_t, 16> uart_queue;
olympux 15:edeb0aed160d 202 Queue<bool, 1> auto_update_queue;
olympux 2:18f10e7209f4 203
olympux 3:972ed747474c 204 Mutex uart_mutex;
olympux 2:18f10e7209f4 205
olympux 2:18f10e7209f4 206
olympux 2:18f10e7209f4 207 /*
olympux 2:18f10e7209f4 208 * Threads
olympux 2:18f10e7209f4 209 */
olympux 0:c2eac797face 210 void uart_thread(void const *args) {
olympux 2:18f10e7209f4 211 message_t *p_message;
olympux 0:c2eac797face 212
olympux 0:c2eac797face 213 while (true) {
olympux 3:972ed747474c 214 osEvent evt = uart_queue.get();
olympux 2:18f10e7209f4 215 if (evt.status == osEventMessage) {
olympux 2:18f10e7209f4 216 p_message = (message_t*)evt.value.p;
olympux 11:709f90a3b599 217 uart_mutex.lock(); // mutex for stdio is not neccessary
olympux 16:84a5bf7285d0 218 //DBG("len=%d\n", p_message->len);
olympux 16:84a5bf7285d0 219 DBG("%s\n", p_message->msg);
olympux 3:972ed747474c 220 uart_mutex.unlock();
olympux 2:18f10e7209f4 221 }
olympux 0:c2eac797face 222 }
olympux 0:c2eac797face 223 }
olympux 0:c2eac797face 224
olympux 0:c2eac797face 225
olympux 15:edeb0aed160d 226 // Timer thread for auto update
olympux 15:edeb0aed160d 227 void auto_update_timer_thread(void const* args) {
olympux 15:edeb0aed160d 228 bool update_flag;
olympux 15:edeb0aed160d 229
olympux 15:edeb0aed160d 230 Thread::wait(500);
olympux 15:edeb0aed160d 231 while(true) {
olympux 15:edeb0aed160d 232 update_flag = true;
olympux 15:edeb0aed160d 233 auto_update_queue.put(&update_flag);
olympux 15:edeb0aed160d 234 Thread::wait(1000*transmit_time_period);
olympux 15:edeb0aed160d 235 }
olympux 15:edeb0aed160d 236 }
olympux 15:edeb0aed160d 237
olympux 15:edeb0aed160d 238
olympux 6:d054e394fba3 239 /*
olympux 6:d054e394fba3 240 * Ethernet init
olympux 6:d054e394fba3 241 */
olympux 4:568c97f2a407 242 int ethernet_init(void) {
olympux 16:84a5bf7285d0 243 DBG("Start initialising ethernet\n");
olympux 14:18eda020a589 244 int ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 0:c2eac797face 245
olympux 0:c2eac797face 246 if (!ret) {
olympux 16:84a5bf7285d0 247 DBG("Initialized, MAC: %s\n", eth.getMACAddress());
olympux 0:c2eac797face 248 } else {
olympux 16:84a5bf7285d0 249 ERR("Error eth.init() - ret = %d\n", ret);
olympux 0:c2eac797face 250 return -1;
olympux 0:c2eac797face 251 }
olympux 0:c2eac797face 252
olympux 0:c2eac797face 253 ret = eth.connect();
olympux 0:c2eac797face 254 if (!ret) {
olympux 16:84a5bf7285d0 255 DBG("IP: %s, MASK: %s, GW: %s\n", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 0:c2eac797face 256 } else {
olympux 16:84a5bf7285d0 257 ERR("Error eth.connect() - ret = %d\n", ret);
olympux 0:c2eac797face 258 return -1;
olympux 0:c2eac797face 259 }
olympux 3:972ed747474c 260
olympux 4:568c97f2a407 261 return 0;
olympux 4:568c97f2a407 262 }
olympux 4:568c97f2a407 263
olympux 4:568c97f2a407 264
olympux 6:d054e394fba3 265
olympux 6:d054e394fba3 266
olympux 4:568c97f2a407 267
olympux 4:568c97f2a407 268 int main()
olympux 4:568c97f2a407 269 {
olympux 4:568c97f2a407 270 message_t message;
olympux 9:d2534ecf88c6 271 int n, ret;
olympux 4:568c97f2a407 272
olympux 15:edeb0aed160d 273 Thread::wait(2000); // turn on delay
olympux 15:edeb0aed160d 274
olympux 4:568c97f2a407 275 /*
olympux 9:d2534ecf88c6 276 * Configure
olympux 4:568c97f2a407 277 */
olympux 11:709f90a3b599 278 uart.baud(115200);
olympux 16:84a5bf7285d0 279 DBG("\r\nStarting...\r\n");
olympux 4:568c97f2a407 280
olympux 4:568c97f2a407 281 /*
olympux 4:568c97f2a407 282 * UI threads
olympux 4:568c97f2a407 283 */
olympux 4:568c97f2a407 284 Thread t1(uart_thread);
olympux 15:edeb0aed160d 285 Thread t2(auto_update_timer_thread);
olympux 15:edeb0aed160d 286
olympux 15:edeb0aed160d 287 //// send to uart
olympux 15:edeb0aed160d 288 //buffer[n] = '\0';
olympux 15:edeb0aed160d 289 //message.len = n;
olympux 15:edeb0aed160d 290 //message.msg = buffer;
olympux 15:edeb0aed160d 291 //uart_queue.put(&message);
olympux 4:568c97f2a407 292
olympux 6:d054e394fba3 293
olympux 6:d054e394fba3 294 /*
olympux 6:d054e394fba3 295 * FLASH
olympux 6:d054e394fba3 296 */
olympux 12:7c152c0ca4d8 297 load_eeprom_network();
olympux 15:edeb0aed160d 298 load_eeprom_tcpserver();
olympux 4:568c97f2a407 299
olympux 4:568c97f2a407 300 /*
olympux 4:568c97f2a407 301 * Ethernet
olympux 4:568c97f2a407 302 */
olympux 6:d054e394fba3 303 ret = ethernet_init();
olympux 4:568c97f2a407 304 if (ret) {
olympux 16:84a5bf7285d0 305 ERR("Ethernet initialisation failed. App halted\r\n");
olympux 4:568c97f2a407 306 while (true) {};
olympux 4:568c97f2a407 307 }
olympux 4:568c97f2a407 308
olympux 12:7c152c0ca4d8 309
olympux 12:7c152c0ca4d8 310 /*
olympux 12:7c152c0ca4d8 311 * TCP/UDP setup
olympux 12:7c152c0ca4d8 312 */
olympux 3:972ed747474c 313 #ifdef TCP_SERVER
olympux 12:7c152c0ca4d8 314 tcp_server.bind(tcp_server_local_port);
olympux 3:972ed747474c 315 tcp_server.listen();
olympux 16:84a5bf7285d0 316 DBG("TCP server started...\r\n");
olympux 4:568c97f2a407 317 tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
olympux 3:972ed747474c 318 #endif
olympux 14:18eda020a589 319
olympux 14:18eda020a589 320 #ifdef TCP_CLIENT
olympux 15:edeb0aed160d 321 //RtosTimer tcp_client_auto_update_timer(tcp_client_auto_update, osTimerPeriodic, NULL);
olympux 14:18eda020a589 322 #endif
olympux 3:972ed747474c 323
olympux 3:972ed747474c 324 #ifdef UDP_SERVER
olympux 12:7c152c0ca4d8 325 ret = udp_server.bind(udp_server_local_port);
olympux 16:84a5bf7285d0 326 DBG("UDP started (sock.bind = %d)\r\n", ret);
olympux 4:568c97f2a407 327 udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
olympux 3:972ed747474c 328 #endif
olympux 3:972ed747474c 329
olympux 3:972ed747474c 330
olympux 12:7c152c0ca4d8 331 /*
olympux 12:7c152c0ca4d8 332 * Network processor
olympux 12:7c152c0ca4d8 333 */
olympux 0:c2eac797face 334 while (true) {
olympux 15:edeb0aed160d 335 #ifdef TCP_CLIENT
olympux 16:84a5bf7285d0 336 // FOR AUTO TRANSMIT DEVICE STATUS
olympux 16:84a5bf7285d0 337 if (auto_transmit_flag == 0xA5A5) {
olympux 16:84a5bf7285d0 338 // connect to TCP server if required
olympux 16:84a5bf7285d0 339 if (!tcp_sock.is_connected()) {
olympux 16:84a5bf7285d0 340 ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port);
olympux 16:84a5bf7285d0 341 if (ret > -1) {
olympux 16:84a5bf7285d0 342 DBG("Successfully connected to %s on port %d\r\n", str_server_ip_addr, u16tcp_server_port);
olympux 16:84a5bf7285d0 343 }
olympux 16:84a5bf7285d0 344 else {
olympux 16:84a5bf7285d0 345 ERR("Unable to connect to %s on port %d\r\n", str_server_ip_addr, u16tcp_server_port);
olympux 16:84a5bf7285d0 346 }
olympux 15:edeb0aed160d 347 }
olympux 16:84a5bf7285d0 348
olympux 16:84a5bf7285d0 349 // transmit data if connected
olympux 16:84a5bf7285d0 350 if (tcp_sock.is_connected()) {
olympux 16:84a5bf7285d0 351 osEvent evt = auto_update_queue.get(1); // timeout after 1ms
olympux 16:84a5bf7285d0 352 if (evt.status == osEventMessage) {
olympux 16:84a5bf7285d0 353 DBG("Updating...\r\n");
olympux 16:84a5bf7285d0 354 update_sending_frame(tcp_client_buffer);
olympux 16:84a5bf7285d0 355 tcp_sock.send_all(tcp_client_buffer, SENDING_PROTOCOL_LENGTH);
olympux 16:84a5bf7285d0 356 }
olympux 15:edeb0aed160d 357 }
olympux 16:84a5bf7285d0 358 } // auto transmit
olympux 15:edeb0aed160d 359 #endif
olympux 15:edeb0aed160d 360
olympux 15:edeb0aed160d 361
olympux 9:d2534ecf88c6 362 // FOR INTERFACING
olympux 4:568c97f2a407 363 #ifdef TCP_SERVER
olympux 4:568c97f2a407 364 // no tcp client connected
olympux 4:568c97f2a407 365 if (!tcp_client.is_connected())
olympux 4:568c97f2a407 366 {
olympux 4:568c97f2a407 367 // wait for client within timeout
olympux 4:568c97f2a407 368 ret = tcp_server.accept(tcp_client);
olympux 2:18f10e7209f4 369
olympux 4:568c97f2a407 370 // tcp client connected
olympux 4:568c97f2a407 371 if (ret > -1) {
olympux 16:84a5bf7285d0 372 DBG("Connection from: %s\r\n", tcp_client.get_address());
olympux 4:568c97f2a407 373
olympux 4:568c97f2a407 374 // loop waiting and receiving data within timeout
olympux 4:568c97f2a407 375 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
olympux 4:568c97f2a407 376 while (true) {
olympux 15:edeb0aed160d 377 n = tcp_client.receive(tcp_server_buffer, sizeof(tcp_server_buffer));
olympux 4:568c97f2a407 378 if (n <= 0) break;
olympux 4:568c97f2a407 379
olympux 9:d2534ecf88c6 380 // got some data, test it
olympux 16:84a5bf7285d0 381 DBG("TCP server received: %s\r\n", tcp_server_buffer);
olympux 9:d2534ecf88c6 382 // process received data
olympux 9:d2534ecf88c6 383 switch (n) {
olympux 9:d2534ecf88c6 384 // length 58-bytes, Receiving protocol
olympux 11:709f90a3b599 385 case RECEIVING_PROTOCOL_LENGTH: {
olympux 16:84a5bf7285d0 386 DBG("Checking device ID...");
olympux 9:d2534ecf88c6 387 // check device id
olympux 15:edeb0aed160d 388 char* id = strstr(tcp_server_buffer, DEVICE_ID);
olympux 9:d2534ecf88c6 389 if (id == NULL)
olympux 9:d2534ecf88c6 390 break;
olympux 15:edeb0aed160d 391 else if ((id - tcp_server_buffer) > 0)
olympux 9:d2534ecf88c6 392 break;
olympux 16:84a5bf7285d0 393 DBG("Correct.\r\n");
olympux 9:d2534ecf88c6 394
olympux 9:d2534ecf88c6 395 // firstly, update outputs if required
olympux 9:d2534ecf88c6 396 // digital outputs
olympux 15:edeb0aed160d 397 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 16:84a5bf7285d0 398 DBG("Update digital outputs\r\n");
olympux 12:7c152c0ca4d8 399 char str_dout[9];
olympux 15:edeb0aed160d 400 memcpy(str_dout, &tcp_server_buffer[RECEIVING_PROTOCOL_DO_POS], 8);
olympux 12:7c152c0ca4d8 401 str_dout[8] = '\0';
olympux 12:7c152c0ca4d8 402 update_digital_outputs(str_dout);
olympux 9:d2534ecf88c6 403 }
olympux 9:d2534ecf88c6 404 // analog output 0
olympux 15:edeb0aed160d 405 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 16:84a5bf7285d0 406 DBG("Update analog output 0\r\n");
olympux 9:d2534ecf88c6 407 }
olympux 11:709f90a3b599 408 // analog output 1
olympux 15:edeb0aed160d 409 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 16:84a5bf7285d0 410 DBG("Update analog output 1\r\n");
olympux 9:d2534ecf88c6 411 }
olympux 9:d2534ecf88c6 412 // UART
olympux 15:edeb0aed160d 413 if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 16:84a5bf7285d0 414 DBG("UART data: ");
olympux 11:709f90a3b599 415 char str_uart[33];
olympux 15:edeb0aed160d 416 memcpy(str_uart, &tcp_server_buffer[RECEIVING_PROTOCOL_UART_POS], 32);
olympux 11:709f90a3b599 417 str_uart[32] = '\0';
olympux 11:709f90a3b599 418 printf("%s\r\n", str_uart);
olympux 9:d2534ecf88c6 419 }
olympux 9:d2534ecf88c6 420
olympux 9:d2534ecf88c6 421 // then, check query status command and sending protocol if required
olympux 15:edeb0aed160d 422 if (tcp_server_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
olympux 16:84a5bf7285d0 423 DBG("Sent device status through TCP\r\n");
olympux 9:d2534ecf88c6 424 // sending protocol
olympux 15:edeb0aed160d 425 update_sending_frame(tcp_server_buffer);
olympux 15:edeb0aed160d 426 tcp_client.send_all(tcp_server_buffer, SENDING_PROTOCOL_LENGTH);
olympux 9:d2534ecf88c6 427 }
olympux 9:d2534ecf88c6 428
olympux 9:d2534ecf88c6 429 break;
olympux 9:d2534ecf88c6 430 }
olympux 9:d2534ecf88c6 431 default:
olympux 9:d2534ecf88c6 432 break;
olympux 9:d2534ecf88c6 433 }
olympux 4:568c97f2a407 434 } // end loop if no data received within timeout
olympux 4:568c97f2a407 435 tcp_client.close();
olympux 4:568c97f2a407 436 } // if client connected
olympux 4:568c97f2a407 437 } // if no client connected
olympux 3:972ed747474c 438 #endif
olympux 3:972ed747474c 439
olympux 9:d2534ecf88c6 440
olympux 9:d2534ecf88c6 441
olympux 9:d2534ecf88c6 442 // ONLY FOR CONFIGRATION
olympux 9:d2534ecf88c6 443 #ifdef UDP_SERVER
olympux 4:568c97f2a407 444 // wait for udp packet within timeout
olympux 15:edeb0aed160d 445 n = udp_server.receiveFrom(ep_udp_client, udp_server_buffer, sizeof(udp_server_buffer));
olympux 9:d2534ecf88c6 446 if (n <= 0) continue;
olympux 3:972ed747474c 447
olympux 9:d2534ecf88c6 448 // got some data, test it
olympux 16:84a5bf7285d0 449 DBG("UDP received: %s\r\n", udp_server_buffer);
olympux 6:d054e394fba3 450 // process received data
olympux 6:d054e394fba3 451 switch (n) {
olympux 9:d2534ecf88c6 452 // length = 6, a CONFIGURATION command (discovery command, TCP port, or UDP port)
olympux 9:d2534ecf88c6 453 // Format: NNIODS, NNIOTP or NNIOUP
olympux 9:d2534ecf88c6 454 case 6:
olympux 7:d45bd480e90f 455 // discovery command
olympux 15:edeb0aed160d 456 if (strstr(udp_server_buffer, "NNIODS") != NULL) {
olympux 14:18eda020a589 457 udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
olympux 10:4cd965d79de0 458 } // NNIODS
olympux 7:d45bd480e90f 459 // ask for TCP server port
olympux 15:edeb0aed160d 460 else if (strstr(udp_server_buffer, "NNIOTP") != NULL) {
olympux 7:d45bd480e90f 461 char port[5];
olympux 12:7c152c0ca4d8 462 sprintf(port, "%5d", tcp_server_local_port);
olympux 7:d45bd480e90f 463 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 10:4cd965d79de0 464 } // NNIOTP
olympux 7:d45bd480e90f 465 // ask for UDP server port
olympux 15:edeb0aed160d 466 else if (strstr(udp_server_buffer, "NNIOUP") != NULL) {
olympux 7:d45bd480e90f 467 char port[5];
olympux 12:7c152c0ca4d8 468 sprintf(port, "%5d", udp_server_local_port);
olympux 7:d45bd480e90f 469 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 10:4cd965d79de0 470 } // NNIOUP
olympux 15:edeb0aed160d 471 else if (strstr(udp_server_buffer, "NNIOTM") != NULL) {
olympux 10:4cd965d79de0 472 #ifdef NTP
olympux 10:4cd965d79de0 473 char str_time[50];
olympux 10:4cd965d79de0 474
olympux 16:84a5bf7285d0 475 DBG("Trying to update time...\r\n");
olympux 10:4cd965d79de0 476 if (ntp.setTime("0.pool.ntp.org") == 0) {
olympux 16:84a5bf7285d0 477 DBG("Set time successfully\r\n");
olympux 10:4cd965d79de0 478 time_t ctTime;
olympux 10:4cd965d79de0 479 ctTime = time(NULL);
olympux 10:4cd965d79de0 480
olympux 16:84a5bf7285d0 481 DBG("Time is set to (UTC): %s\r\n", ctime(&ctTime));
olympux 10:4cd965d79de0 482 sprintf(str_time, "%s", ctime(&ctTime));
olympux 10:4cd965d79de0 483 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 484 }
olympux 10:4cd965d79de0 485 else {
olympux 16:84a5bf7285d0 486 WARN("Error\r\n");
olympux 10:4cd965d79de0 487 sprintf(str_time, "ERR");
olympux 10:4cd965d79de0 488 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 489 }
olympux 10:4cd965d79de0 490 #elif
olympux 16:84a5bf7285d0 491 WARN("NTP disabled\r\n");
olympux 10:4cd965d79de0 492 sprintf(str_time, "DIS");
olympux 10:4cd965d79de0 493 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 10:4cd965d79de0 494 #endif
olympux 10:4cd965d79de0 495 } // NNIOTM
olympux 10:4cd965d79de0 496
olympux 7:d45bd480e90f 497 break;
olympux 9:d2534ecf88c6 498 // length = 19, SET NETWORK CONFIGURATION
olympux 9:d2534ecf88c6 499 // Format: 4E 4E 49 4F C0 A8 00 78 FF FF FF 00 C0 A8 00 01 00 00 01
olympux 9:d2534ecf88c6 500 // (NNIO; IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
olympux 9:d2534ecf88c6 501 case 19:{
olympux 9:d2534ecf88c6 502 // check device id
olympux 15:edeb0aed160d 503 char* id = strstr(udp_server_buffer, DEVICE_ID);
olympux 9:d2534ecf88c6 504 if (id == NULL)
olympux 9:d2534ecf88c6 505 break;
olympux 15:edeb0aed160d 506 else if ((id - udp_server_buffer) > 0)
olympux 9:d2534ecf88c6 507 break;
olympux 9:d2534ecf88c6 508
olympux 16:84a5bf7285d0 509 DBG("Received user configuration\r\n");
olympux 15:edeb0aed160d 510 write_eeprom_network(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
olympux 15:edeb0aed160d 511 break;
olympux 15:edeb0aed160d 512 }
olympux 15:edeb0aed160d 513 // length = 12, SET TCP SERVER CONFIGURATION
olympux 15:edeb0aed160d 514 // auto update & its time period, TCP server configuration (IP & port)
olympux 15:edeb0aed160d 515 // Format: 4E 4E 49 4F 5A 01 C0 A8 00 09 E0 2E (LSB MSB)
olympux 15:edeb0aed160d 516 // NNIO Auto 1s 192.168.0.9 12000
olympux 15:edeb0aed160d 517 case 12: {
olympux 15:edeb0aed160d 518 char* id = strstr(udp_server_buffer, DEVICE_ID);
olympux 15:edeb0aed160d 519 if (id == NULL)
olympux 15:edeb0aed160d 520 break;
olympux 15:edeb0aed160d 521 else if ((id - udp_server_buffer) > 0)
olympux 15:edeb0aed160d 522 break;
olympux 15:edeb0aed160d 523
olympux 16:84a5bf7285d0 524 DBG("Received TCP server configuration\r\n");
olympux 15:edeb0aed160d 525 write_eeprom_tcpserver(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
olympux 6:d054e394fba3 526 break;
olympux 9:d2534ecf88c6 527 }
olympux 6:d054e394fba3 528 default:
olympux 6:d054e394fba3 529 break;
olympux 4:568c97f2a407 530 }
olympux 3:972ed747474c 531 #endif
olympux 4:568c97f2a407 532 } // network processor
olympux 11:709f90a3b599 533 }
olympux 11:709f90a3b599 534
olympux 12:7c152c0ca4d8 535 /*
olympux 12:7c152c0ca4d8 536 * Update digital outputs following receiving frame from TCP client
olympux 12:7c152c0ca4d8 537 */
olympux 12:7c152c0ca4d8 538 void update_digital_outputs(char* buf) {
olympux 16:84a5bf7285d0 539 DBG("Digital outputs: %s\n", buf);
olympux 11:709f90a3b599 540
olympux 12:7c152c0ca4d8 541 dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 542 dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 543 dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 544 dout3 = (buf[3] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 545 dout4 = (buf[4] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 546 dout5 = (buf[5] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 547 dout6 = (buf[6] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 548 dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 549 }
olympux 12:7c152c0ca4d8 550
olympux 12:7c152c0ca4d8 551 void update_sending_frame(char* buf) {
olympux 12:7c152c0ca4d8 552 memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_ID, 4); // device id
olympux 12:7c152c0ca4d8 553 memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
olympux 12:7c152c0ca4d8 554 memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4);
olympux 11:709f90a3b599 555
olympux 12:7c152c0ca4d8 556 buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 557 buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 558 buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 559 buf[SENDING_PROTOCOL_DI_POS+3] = (din3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 560 buf[SENDING_PROTOCOL_DI_POS+4] = (din4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 561 buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 562 buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 563 buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 564
olympux 12:7c152c0ca4d8 565 buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 566 buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 567 buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 568 buf[SENDING_PROTOCOL_DO_POS+3] = (dout3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 569 buf[SENDING_PROTOCOL_DO_POS+4] = (dout4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 570 buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 571 buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 572 buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 573
olympux 15:edeb0aed160d 574 uint16_t val = ain0.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 575 memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 576 val = ain1.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 577 memcpy(&buf[SENDING_PROTOCOL_AI1_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 578 val = 0x0180;
olympux 15:edeb0aed160d 579 memcpy(&buf[SENDING_PROTOCOL_AO0_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 580 val = 0x0180;
olympux 15:edeb0aed160d 581 memcpy(&buf[SENDING_PROTOCOL_AO1_POS], &val, 2); // LSB MSB
olympux 12:7c152c0ca4d8 582 buf[SENDING_PROTOCOL_CR_POS] = 0x0D;
olympux 12:7c152c0ca4d8 583 buf[SENDING_PROTOCOL_CR_POS+1] = '\0';
olympux 4:568c97f2a407 584 }