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:
Sun Dec 07 00:18:07 2014 +0000
Revision:
25:48dd18cc147c
Parent:
24:ca0199b8a3aa
Child:
26:09e0dd020900
Update to 1.2.1. Tested.

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 #include "mbed.h"
olympux 12:7c152c0ca4d8 6 #include "eeprom.h"
olympux 0:c2eac797face 7 #include "EthernetInterface.h"
olympux 9:d2534ecf88c6 8 #include "NTPClient.h"
olympux 0:c2eac797face 9 #include "rtos.h"
olympux 0:c2eac797face 10
olympux 12:7c152c0ca4d8 11 #include "my_eeprom_funcs.h"
olympux 20:71c7950fdd91 12 #include "Watchdog.h"
olympux 12:7c152c0ca4d8 13
olympux 0:c2eac797face 14
olympux 16:84a5bf7285d0 15 //Debug is disabled by default
olympux 25:48dd18cc147c 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 20:71c7950fdd91 71 // Watchdog
olympux 20:71c7950fdd91 72 Watchdog wdt;
olympux 20:71c7950fdd91 73
olympux 20:71c7950fdd91 74
olympux 12:7c152c0ca4d8 75 void update_digital_outputs(char* buf);
olympux 12:7c152c0ca4d8 76 void update_sending_frame(char* buf);
olympux 11:709f90a3b599 77
olympux 9:d2534ecf88c6 78
olympux 9:d2534ecf88c6 79
olympux 13:bcf840da68fd 80 /*
olympux 13:bcf840da68fd 81 * EEPROM section
olympux 13:bcf840da68fd 82 */
olympux 6:d054e394fba3 83 // Virtual address defined by the user: 0xFFFF value is prohibited
olympux 6:d054e394fba3 84 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
olympux 6:d054e394fba3 85 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
olympux 6:d054e394fba3 86 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
olympux 6:d054e394fba3 87 0x4212, // TCP server port, not used
olympux 8:64848959adb9 88 0x5212, // UDP server port, not used
olympux 16:84a5bf7285d0 89 0x8888, // 1st run? 0xA5A5 = configured
olympux 12:7c152c0ca4d8 90 0x6212, 0x6313, 0x6414, // MAC
olympux 12:7c152c0ca4d8 91
olympux 12:7c152c0ca4d8 92 // this section is for the TCP server that this device connects to in TCP client mode
olympux 16:84a5bf7285d0 93 0x7212, 0x7313, // 0xA5 = auto transmit status, time period
olympux 12:7c152c0ca4d8 94 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
olympux 16:84a5bf7285d0 95 0x9212, // TCP server port
olympux 16:84a5bf7285d0 96
olympux 16:84a5bf7285d0 97 // this section is for selecting protocol
olympux 16:84a5bf7285d0 98 0xA212, // 0xA5A5 = enable TCP server
olympux 16:84a5bf7285d0 99 0xA313, // 0xA5A5 = eanble TCP client
olympux 18:ca499a2e7da6 100 0xA414 // 0xA5A5 = enable UDP server
olympux 6:d054e394fba3 101 };
olympux 0:c2eac797face 102
olympux 2:18f10e7209f4 103 /*
olympux 2:18f10e7209f4 104 * Network configuration
olympux 2:18f10e7209f4 105 */
olympux 4:568c97f2a407 106 #define TCP_SERVER
olympux 15:edeb0aed160d 107 #define TCP_CLIENT
olympux 4:568c97f2a407 108 #define UDP_SERVER
olympux 4:568c97f2a407 109 //#define UDP_CLIENT
olympux 10:4cd965d79de0 110 #define NTP
olympux 4:568c97f2a407 111
olympux 20:71c7950fdd91 112 #define TCP_SERVER_WAIT_CLIENT_TIMEOUT 200 // timeout for local tcp server wait for a remote client
olympux 20:71c7950fdd91 113 #define TCP_SERVER_RECEIVE_TIMEOUT 2000 // timeout for local tcp server wait to receive from remote client
olympux 20:71c7950fdd91 114 #define TCP_CLIENT_RECEIVE_TIMEOUT 200 // timeout for local tcp client try to connect remote server
olympux 20:71c7950fdd91 115 #define UDP_SERVER_RECEIVE_TIMEOUT 100 // timeout for checking config command
olympux 4:568c97f2a407 116
olympux 15:edeb0aed160d 117
olympux 15:edeb0aed160d 118 // TCP server function
olympux 15:edeb0aed160d 119 TCPSocketServer tcp_server;
olympux 15:edeb0aed160d 120 TCPSocketConnection tcp_client;
olympux 15:edeb0aed160d 121 // TCP client function
olympux 15:edeb0aed160d 122 TCPSocketConnection tcp_sock;
olympux 15:edeb0aed160d 123 // UDP server
olympux 15:edeb0aed160d 124 UDPSocket udp_server;
olympux 15:edeb0aed160d 125 Endpoint ep_udp_client;
olympux 15:edeb0aed160d 126 // NTP
olympux 13:bcf840da68fd 127 NTPClient ntp;
olympux 13:bcf840da68fd 128
olympux 13:bcf840da68fd 129
olympux 15:edeb0aed160d 130
olympux 13:bcf840da68fd 131 /*
olympux 13:bcf840da68fd 132 * Variables for network configuration, server
olympux 13:bcf840da68fd 133 */
olympux 11:709f90a3b599 134 uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits
olympux 11:709f90a3b599 135 uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom
olympux 11:709f90a3b599 136 char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx
olympux 25:48dd18cc147c 137 uint16_t configured_ip = 0; // static ip configured flag
olympux 9:d2534ecf88c6 138
olympux 22:e5f0aa929c44 139 const uint16_t tcp_server_local_port = 10000; // fixed, change to 7000 if internet required
olympux 12:7c152c0ca4d8 140 const uint16_t udp_server_local_port = 11000; // fixed
olympux 12:7c152c0ca4d8 141
olympux 12:7c152c0ca4d8 142 // TCP client: this section is used for the TCP server that this device connects to in TCP client mode
olympux 12:7c152c0ca4d8 143 // this device will transmit status every transmit_time_period
olympux 12:7c152c0ca4d8 144 uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
olympux 12:7c152c0ca4d8 145 uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
olympux 14:18eda020a589 146 uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
olympux 14:18eda020a589 147 char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
olympux 12:7c152c0ca4d8 148 uint16_t u16tcp_server_port; // directly loaded from eeprom
olympux 18:ca499a2e7da6 149 uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
olympux 12:7c152c0ca4d8 150
olympux 19:05934ee9ee67 151 char tcp_receiving_buffer[256];
olympux 19:05934ee9ee67 152 char tcp_sending_buffer[256]; // socket buffer
olympux 19:05934ee9ee67 153 char udp_receiving_buffer[256];
olympux 12:7c152c0ca4d8 154
olympux 0:c2eac797face 155
olympux 13:bcf840da68fd 156 /*
olympux 13:bcf840da68fd 157 * Protocol
olympux 13:bcf840da68fd 158 */
olympux 9:d2534ecf88c6 159 // Commands
olympux 17:88ef7a078095 160 #define DEVICE_ID "NNIO"
olympux 17:88ef7a078095 161
olympux 17:88ef7a078095 162 #define RECEIVING_PROTOCOL_LENGTH 58
olympux 17:88ef7a078095 163 #define SENDING_PROTOCOL_LENGTH 39
olympux 17:88ef7a078095 164 #define QUERY_CMD_LENGTH 6
olympux 17:88ef7a078095 165 #define SET_NETWORK_CONFIG_CMD_LENGTH 19
olympux 17:88ef7a078095 166 #define UPDATE_TCP_SERVER_INFO_CMD_LENGTH 12
olympux 17:88ef7a078095 167
olympux 17:88ef7a078095 168 #define QUERY_DISCOVERY_CMD "NNIODS"
olympux 17:88ef7a078095 169 #define QUERY_IP_CMD "NNIOIP"
olympux 17:88ef7a078095 170 #define QUERY_SUBNET_CMD "NNIOSN"
olympux 17:88ef7a078095 171 #define QUERY_GATEWAY_CMD "NNIOGW"
olympux 17:88ef7a078095 172 #define QUERY_MAC_CMD "NNIOMC"
olympux 17:88ef7a078095 173 #define QUERY_UDP_PORT_CMD "NNIOUP"
olympux 17:88ef7a078095 174 #define QUERY_TCP_PORT_CMD "NNIOTP"
olympux 17:88ef7a078095 175 #define QUERY_UPDATE_TIME_CMD "NNIOTM"
olympux 11:709f90a3b599 176 #define RECEIVING_PROTOCOL_ENABLE_OUTPUT 'O'
olympux 11:709f90a3b599 177 #define QUERY_STATUS_COMMAND 'Q'
olympux 11:709f90a3b599 178 #define DIGITAL_HIGH 'H'
olympux 11:709f90a3b599 179 #define DIGITAL_LOW 'L'
olympux 9:d2534ecf88c6 180
olympux 9:d2534ecf88c6 181
olympux 9:d2534ecf88c6 182 // Positions
olympux 11:709f90a3b599 183 #define RECEIVING_PROTOCOL_ID_POS 0
olympux 9:d2534ecf88c6 184 #define RECEIVING_PROTOCOL_OP_POS 4
olympux 9:d2534ecf88c6 185 #define RECEIVING_PROTOCOL_EN_DO_POS RECEIVING_PROTOCOL_OP_POS + 0
olympux 9:d2534ecf88c6 186 #define RECEIVING_PROTOCOL_EN_A0O_POS RECEIVING_PROTOCOL_OP_POS + 1
olympux 9:d2534ecf88c6 187 #define RECEIVING_PROTOCOL_EN_A1O_POS RECEIVING_PROTOCOL_OP_POS + 2
olympux 9:d2534ecf88c6 188 #define RECEIVING_PROTOCOL_EN_UART_POS RECEIVING_PROTOCOL_OP_POS + 3
olympux 9:d2534ecf88c6 189 #define RECEIVING_PROTOCOL_COMMAND_POS RECEIVING_PROTOCOL_OP_POS + 4
olympux 11:709f90a3b599 190
olympux 11:709f90a3b599 191 #define RECEIVING_PROTOCOL_IP_POS 9
olympux 11:709f90a3b599 192 #define RECEIVING_PROTOCOL_DO_POS 13
olympux 11:709f90a3b599 193 #define RECEIVING_PROTOCOL_A0O_POS 21
olympux 11:709f90a3b599 194 #define RECEIVING_PROTOCOL_A01_POS 23
olympux 11:709f90a3b599 195 #define RECEIVING_PROTOCOL_UART_POS 25
olympux 9:d2534ecf88c6 196
olympux 9:d2534ecf88c6 197
olympux 11:709f90a3b599 198 #define SENDING_PROTOCOL_ID_POS 0
olympux 11:709f90a3b599 199 #define SENDING_PROTOCOL_MAC_POS 4
olympux 11:709f90a3b599 200 #define SENDING_PROTOCOL_IP_POS 10
olympux 11:709f90a3b599 201 #define SENDING_PROTOCOL_DI_POS 14
olympux 11:709f90a3b599 202 #define SENDING_PROTOCOL_DO_POS 22
olympux 11:709f90a3b599 203 #define SENDING_PROTOCOL_AI0_POS 30
olympux 11:709f90a3b599 204 #define SENDING_PROTOCOL_AI1_POS 32
olympux 11:709f90a3b599 205 #define SENDING_PROTOCOL_AO0_POS 34
olympux 11:709f90a3b599 206 #define SENDING_PROTOCOL_AO1_POS 36
olympux 11:709f90a3b599 207 #define SENDING_PROTOCOL_CR_POS 38
olympux 0:c2eac797face 208
olympux 2:18f10e7209f4 209
olympux 2:18f10e7209f4 210 /*
olympux 2:18f10e7209f4 211 * RTOS
olympux 2:18f10e7209f4 212 */
olympux 2:18f10e7209f4 213 struct message_t {
olympux 2:18f10e7209f4 214 int len;
olympux 2:18f10e7209f4 215 char *msg;
olympux 2:18f10e7209f4 216 };
olympux 3:972ed747474c 217 Queue<message_t, 16> uart_queue;
olympux 15:edeb0aed160d 218 Queue<bool, 1> auto_update_queue;
olympux 2:18f10e7209f4 219
olympux 2:18f10e7209f4 220
olympux 2:18f10e7209f4 221 /*
olympux 2:18f10e7209f4 222 * Threads
olympux 2:18f10e7209f4 223 */
olympux 15:edeb0aed160d 224 // Timer thread for auto update
olympux 15:edeb0aed160d 225 void auto_update_timer_thread(void const* args) {
olympux 18:ca499a2e7da6 226 bool update_flag = true;
olympux 15:edeb0aed160d 227
olympux 15:edeb0aed160d 228 Thread::wait(500);
olympux 15:edeb0aed160d 229 while(true) {
olympux 15:edeb0aed160d 230 auto_update_queue.put(&update_flag);
olympux 18:ca499a2e7da6 231 Thread::wait(1000*transmit_time_period); // Thread::wait() in ms
olympux 15:edeb0aed160d 232 }
olympux 15:edeb0aed160d 233 }
olympux 15:edeb0aed160d 234
olympux 15:edeb0aed160d 235
olympux 20:71c7950fdd91 236 // WDT reset
olympux 20:71c7950fdd91 237 void wdt_reset_thread(void const* args) {
olympux 20:71c7950fdd91 238 while (true)
olympux 20:71c7950fdd91 239 wdt.Service();
olympux 20:71c7950fdd91 240 }
olympux 20:71c7950fdd91 241
olympux 20:71c7950fdd91 242
olympux 6:d054e394fba3 243 /*
olympux 6:d054e394fba3 244 * Ethernet init
olympux 6:d054e394fba3 245 */
olympux 4:568c97f2a407 246 int ethernet_init(void) {
olympux 25:48dd18cc147c 247 int dhcp_ret, ret;
olympux 25:48dd18cc147c 248
olympux 18:ca499a2e7da6 249 DBG("Start initialising ethernet");
olympux 25:48dd18cc147c 250
olympux 25:48dd18cc147c 251 // if not configured, try dhcp
olympux 25:48dd18cc147c 252 dhcp_ret = -1;
olympux 25:48dd18cc147c 253 if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 25:48dd18cc147c 254 DBG("Connecting DHCP server...");
olympux 25:48dd18cc147c 255 dhcp_ret = eth.init(u8mac);
olympux 25:48dd18cc147c 256 if (dhcp_ret == 0)
olympux 25:48dd18cc147c 257 dhcp_ret = eth.connect();
olympux 25:48dd18cc147c 258 }
olympux 25:48dd18cc147c 259
olympux 25:48dd18cc147c 260 if (dhcp_ret != 0) {
olympux 25:48dd18cc147c 261 DBG("No DHCP, load static IP configuration");
olympux 25:48dd18cc147c 262 ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 25:48dd18cc147c 263 } else {
olympux 25:48dd18cc147c 264 snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
olympux 25:48dd18cc147c 265 snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
olympux 25:48dd18cc147c 266 snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
olympux 25:48dd18cc147c 267 ret = 0;
olympux 25:48dd18cc147c 268 }
olympux 0:c2eac797face 269
olympux 25:48dd18cc147c 270 if (ret == 0) {
olympux 18:ca499a2e7da6 271 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 0:c2eac797face 272 } else {
olympux 18:ca499a2e7da6 273 ERR("Error eth.init() - ret = %d", ret);
olympux 0:c2eac797face 274 return -1;
olympux 0:c2eac797face 275 }
olympux 0:c2eac797face 276
olympux 0:c2eac797face 277 ret = eth.connect();
olympux 0:c2eac797face 278 if (!ret) {
olympux 18:ca499a2e7da6 279 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 0:c2eac797face 280 } else {
olympux 18:ca499a2e7da6 281 ERR("Error eth.connect() - ret = %d", ret);
olympux 0:c2eac797face 282 return -1;
olympux 0:c2eac797face 283 }
olympux 3:972ed747474c 284
olympux 4:568c97f2a407 285 return 0;
olympux 4:568c97f2a407 286 }
olympux 4:568c97f2a407 287
olympux 4:568c97f2a407 288
olympux 19:05934ee9ee67 289 /*
olympux 19:05934ee9ee67 290 * Procedure to process receiving protocol
olympux 19:05934ee9ee67 291 */
olympux 25:48dd18cc147c 292 void process_received_net_data(char* received_buffer, int len)
olympux 19:05934ee9ee67 293 {
olympux 19:05934ee9ee67 294 char* received_frame;
olympux 19:05934ee9ee67 295 int pos;
olympux 19:05934ee9ee67 296
olympux 19:05934ee9ee67 297 while (len >= RECEIVING_PROTOCOL_LENGTH) {
olympux 19:05934ee9ee67 298 // find device ID
olympux 19:05934ee9ee67 299 DBG("Checking device ID...");
olympux 19:05934ee9ee67 300 char* id = strstr(received_buffer, DEVICE_ID);
olympux 19:05934ee9ee67 301 if (id == NULL) {
olympux 19:05934ee9ee67 302 DBG("No device ID found");
olympux 19:05934ee9ee67 303 break;
olympux 19:05934ee9ee67 304 }
olympux 19:05934ee9ee67 305 pos = id - received_buffer;
olympux 19:05934ee9ee67 306 DBG("Found a frame at %d", pos);
olympux 19:05934ee9ee67 307
olympux 19:05934ee9ee67 308 // extract this frame
olympux 19:05934ee9ee67 309 received_frame = &received_buffer[pos];
olympux 19:05934ee9ee67 310 // calculate the rest
olympux 19:05934ee9ee67 311 received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH];
olympux 19:05934ee9ee67 312 len -= RECEIVING_PROTOCOL_LENGTH;
olympux 19:05934ee9ee67 313
olympux 19:05934ee9ee67 314 // process this received frame
olympux 19:05934ee9ee67 315 // firstly, update outputs if required
olympux 19:05934ee9ee67 316 // digital outputs
olympux 19:05934ee9ee67 317 if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 19:05934ee9ee67 318 DBG("Update digital outputs");
olympux 19:05934ee9ee67 319 char str_dout[9];
olympux 19:05934ee9ee67 320 memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8);
olympux 19:05934ee9ee67 321 str_dout[8] = '\0';
olympux 19:05934ee9ee67 322 update_digital_outputs(str_dout);
olympux 19:05934ee9ee67 323 }
olympux 19:05934ee9ee67 324 // analog output 0
olympux 19:05934ee9ee67 325 if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 19:05934ee9ee67 326 DBG("Update analog output 0");
olympux 19:05934ee9ee67 327 }
olympux 19:05934ee9ee67 328 // analog output 1
olympux 19:05934ee9ee67 329 if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 19:05934ee9ee67 330 DBG("Update analog output 1");
olympux 19:05934ee9ee67 331 }
olympux 19:05934ee9ee67 332 // UART
olympux 19:05934ee9ee67 333 if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
olympux 19:05934ee9ee67 334 DBG("UART data: ");
olympux 19:05934ee9ee67 335 char str_uart[33];
olympux 19:05934ee9ee67 336 memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32);
olympux 19:05934ee9ee67 337 str_uart[32] = '\0';
olympux 24:ca0199b8a3aa 338 uart.printf("%s\r\n", str_uart);
olympux 19:05934ee9ee67 339 }
olympux 19:05934ee9ee67 340
olympux 19:05934ee9ee67 341 // then, check query status command and sending protocol if required
olympux 19:05934ee9ee67 342 if (received_frame[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
olympux 19:05934ee9ee67 343 DBG("Requested to send device status through TCP");
olympux 19:05934ee9ee67 344 // sending protocol
olympux 19:05934ee9ee67 345 update_sending_frame(tcp_sending_buffer);
olympux 19:05934ee9ee67 346 tcp_client.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
olympux 19:05934ee9ee67 347 DBG("Sent");
olympux 19:05934ee9ee67 348 }
olympux 19:05934ee9ee67 349 }
olympux 19:05934ee9ee67 350
olympux 19:05934ee9ee67 351 DBG("Successful");
olympux 19:05934ee9ee67 352 }
olympux 6:d054e394fba3 353
olympux 4:568c97f2a407 354
olympux 4:568c97f2a407 355 int main()
olympux 4:568c97f2a407 356 {
olympux 9:d2534ecf88c6 357 int n, ret;
olympux 4:568c97f2a407 358
olympux 20:71c7950fdd91 359 Thread::wait(500); // turn on delay
olympux 20:71c7950fdd91 360
olympux 4:568c97f2a407 361 /*
olympux 9:d2534ecf88c6 362 * Configure
olympux 4:568c97f2a407 363 */
olympux 11:709f90a3b599 364 uart.baud(115200);
olympux 18:ca499a2e7da6 365 DBG("\r\nStarting...");
olympux 20:71c7950fdd91 366
olympux 20:71c7950fdd91 367 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 368 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 369 wdt.Configure(4);
olympux 6:d054e394fba3 370
olympux 6:d054e394fba3 371 /*
olympux 6:d054e394fba3 372 * FLASH
olympux 6:d054e394fba3 373 */
olympux 12:7c152c0ca4d8 374 load_eeprom_network();
olympux 15:edeb0aed160d 375 load_eeprom_tcpserver();
olympux 20:71c7950fdd91 376
olympux 20:71c7950fdd91 377 /*
olympux 20:71c7950fdd91 378 * UI threads
olympux 20:71c7950fdd91 379 */
olympux 20:71c7950fdd91 380 Thread t2(auto_update_timer_thread);
olympux 20:71c7950fdd91 381 Thread t3(wdt_reset_thread);
olympux 20:71c7950fdd91 382
olympux 4:568c97f2a407 383 /*
olympux 4:568c97f2a407 384 * Ethernet
olympux 4:568c97f2a407 385 */
olympux 6:d054e394fba3 386 ret = ethernet_init();
olympux 4:568c97f2a407 387 if (ret) {
olympux 18:ca499a2e7da6 388 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 389 while (true) {};
olympux 4:568c97f2a407 390 }
olympux 4:568c97f2a407 391
olympux 23:47ee805435b1 392 Thread::wait(2000); // TCP/UDP stack delay
olympux 12:7c152c0ca4d8 393
olympux 12:7c152c0ca4d8 394 /*
olympux 20:71c7950fdd91 395 * UDP server
olympux 20:71c7950fdd91 396 * TCP server/client
olympux 12:7c152c0ca4d8 397 */
olympux 20:71c7950fdd91 398 #ifdef UDP_SERVER
olympux 20:71c7950fdd91 399 ret = udp_server.bind(udp_server_local_port);
olympux 20:71c7950fdd91 400 DBG("UDP server started (sock.bind = %d)...", ret);
olympux 20:71c7950fdd91 401 udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
olympux 20:71c7950fdd91 402 #endif
olympux 20:71c7950fdd91 403
olympux 3:972ed747474c 404 #ifdef TCP_SERVER
olympux 12:7c152c0ca4d8 405 tcp_server.bind(tcp_server_local_port);
olympux 3:972ed747474c 406 tcp_server.listen();
olympux 18:ca499a2e7da6 407 DBG("TCP server started...");
olympux 4:568c97f2a407 408 tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
olympux 3:972ed747474c 409 #endif
olympux 14:18eda020a589 410
olympux 14:18eda020a589 411 #ifdef TCP_CLIENT
olympux 18:ca499a2e7da6 412
olympux 14:18eda020a589 413 #endif
olympux 3:972ed747474c 414
olympux 12:7c152c0ca4d8 415 /*
olympux 19:05934ee9ee67 416 * Network loop processor
olympux 12:7c152c0ca4d8 417 */
olympux 0:c2eac797face 418 while (true) {
olympux 15:edeb0aed160d 419 #ifdef TCP_CLIENT
olympux 18:ca499a2e7da6 420 // FOR AUTO TRANSMIT DEVICE STATUS
olympux 18:ca499a2e7da6 421 //if ((u16enable_tcp_client == 0xA5A5) && (auto_transmit_flag == 0xA5A5)) {
olympux 18:ca499a2e7da6 422 if (auto_transmit_flag == 0xA5A5) {
olympux 18:ca499a2e7da6 423 // connect to TCP server if required
olympux 18:ca499a2e7da6 424 if (!tcp_sock.is_connected()) {
olympux 20:71c7950fdd91 425 ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port); // timeout is default in connect() in W5500.h
olympux 18:ca499a2e7da6 426 if (ret > -1) {
olympux 18:ca499a2e7da6 427 DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port);
olympux 18:ca499a2e7da6 428 }
olympux 18:ca499a2e7da6 429 else {
olympux 18:ca499a2e7da6 430 ERR("Unable to connect to %s on port %d", str_server_ip_addr, u16tcp_server_port);
olympux 18:ca499a2e7da6 431 }
olympux 16:84a5bf7285d0 432 }
olympux 18:ca499a2e7da6 433
olympux 18:ca499a2e7da6 434 // transmit data if connected
olympux 18:ca499a2e7da6 435 if (tcp_sock.is_connected()) {
olympux 18:ca499a2e7da6 436 osEvent evt = auto_update_queue.get(1); // timeout after 1ms
olympux 18:ca499a2e7da6 437 if (evt.status == osEventMessage) {
olympux 18:ca499a2e7da6 438 DBG("Updating...");
olympux 19:05934ee9ee67 439 update_sending_frame(tcp_sending_buffer);
olympux 19:05934ee9ee67 440 tcp_sock.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
olympux 19:05934ee9ee67 441 }
olympux 19:05934ee9ee67 442
olympux 19:05934ee9ee67 443 // check to receive or timeout
olympux 19:05934ee9ee67 444 tcp_sock.set_blocking(false, TCP_CLIENT_RECEIVE_TIMEOUT);
olympux 19:05934ee9ee67 445 n = tcp_sock.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
olympux 19:05934ee9ee67 446 if (n > 0) {
olympux 19:05934ee9ee67 447 // got some data, test it
olympux 19:05934ee9ee67 448 DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer);
olympux 25:48dd18cc147c 449 process_received_net_data(tcp_receiving_buffer, n);
olympux 18:ca499a2e7da6 450 }
olympux 16:84a5bf7285d0 451 }
olympux 18:ca499a2e7da6 452 } // if tcp client enabled && auto transmit
olympux 15:edeb0aed160d 453 #endif
olympux 15:edeb0aed160d 454
olympux 15:edeb0aed160d 455
olympux 9:d2534ecf88c6 456 // FOR INTERFACING
olympux 4:568c97f2a407 457 #ifdef TCP_SERVER
olympux 4:568c97f2a407 458 // no tcp client connected
olympux 18:ca499a2e7da6 459 //if ((u16enable_tcp_server == 0xA5A5) && (!tcp_client.is_connected())) {
olympux 20:71c7950fdd91 460 //if (!tcp_client.is_connected()) {
olympux 20:71c7950fdd91 461 if (1) {
olympux 4:568c97f2a407 462 // wait for client within timeout
olympux 4:568c97f2a407 463 ret = tcp_server.accept(tcp_client);
olympux 2:18f10e7209f4 464
olympux 4:568c97f2a407 465 // tcp client connected
olympux 4:568c97f2a407 466 if (ret > -1) {
olympux 18:ca499a2e7da6 467 DBG("Connection from: %s", tcp_client.get_address());
olympux 4:568c97f2a407 468
olympux 4:568c97f2a407 469 // loop waiting and receiving data within timeout
olympux 4:568c97f2a407 470 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
olympux 4:568c97f2a407 471 while (true) {
olympux 19:05934ee9ee67 472 n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
olympux 4:568c97f2a407 473 if (n <= 0) break;
olympux 4:568c97f2a407 474
olympux 9:d2534ecf88c6 475 // got some data, test it
olympux 19:05934ee9ee67 476 DBG("TCP server received: %s", tcp_receiving_buffer);
olympux 25:48dd18cc147c 477 process_received_net_data(tcp_receiving_buffer, n);
olympux 4:568c97f2a407 478 } // end loop if no data received within timeout
olympux 4:568c97f2a407 479 } // if client connected
olympux 20:71c7950fdd91 480 tcp_client.close();
olympux 18:ca499a2e7da6 481 } // if tcp server enabled && no client connected
olympux 3:972ed747474c 482 #endif
olympux 20:71c7950fdd91 483
olympux 9:d2534ecf88c6 484 #ifdef UDP_SERVER
olympux 25:48dd18cc147c 485 bool config_mode_flag;
olympux 25:48dd18cc147c 486
olympux 19:05934ee9ee67 487 n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
olympux 25:48dd18cc147c 488
olympux 25:48dd18cc147c 489 // check to see if it is a query command
olympux 25:48dd18cc147c 490 // if yes, is it a discovery command or an ip query to enter config mode
olympux 25:48dd18cc147c 491 config_mode_flag = false;
olympux 21:fae96e0d6bb1 492 if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
olympux 25:48dd18cc147c 493 DBG("Received discovery command");
olympux 25:48dd18cc147c 494 char str[50];
olympux 25:48dd18cc147c 495 sprintf(str, "%s%s%s", DEVICE_ID, eth.getMACAddress(), eth.getIPAddress());
olympux 25:48dd18cc147c 496 udp_server.sendTo(ep_udp_client, str, strlen(str));
olympux 25:48dd18cc147c 497 } // NNIODS
olympux 25:48dd18cc147c 498 else if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
olympux 25:48dd18cc147c 499 config_mode_flag = true;
olympux 20:71c7950fdd91 500 DBG("Enabled configuration mode...");
olympux 20:71c7950fdd91 501 DBG("!!! RESET when finished");
olympux 25:48dd18cc147c 502 }
olympux 25:48dd18cc147c 503
olympux 25:48dd18cc147c 504 if (config_mode_flag) {
olympux 25:48dd18cc147c 505 // if receive any config command, stay in config mode forever
olympux 20:71c7950fdd91 506 while (n > 0) {
olympux 20:71c7950fdd91 507 // got some data, test it
olympux 20:71c7950fdd91 508 DBG("UDP received (%s) from (%s) and port (%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
olympux 23:47ee805435b1 509
olympux 20:71c7950fdd91 510 // process received data
olympux 23:47ee805435b1 511 // a configuration command always starts with NN
olympux 23:47ee805435b1 512 if ((udp_receiving_buffer[0] == 'N') && (udp_receiving_buffer[1] == 'N')) {
olympux 23:47ee805435b1 513 switch (n) {
olympux 23:47ee805435b1 514 // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
olympux 23:47ee805435b1 515 // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
olympux 23:47ee805435b1 516 case QUERY_CMD_LENGTH:
olympux 25:48dd18cc147c 517 if (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL) {
olympux 23:47ee805435b1 518 udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
olympux 23:47ee805435b1 519 } // NNIOIP
olympux 23:47ee805435b1 520 else if (strstr(udp_receiving_buffer, QUERY_SUBNET_CMD) != NULL) {
olympux 23:47ee805435b1 521 udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
olympux 23:47ee805435b1 522 } // NNIOSN
olympux 23:47ee805435b1 523 else if (strstr(udp_receiving_buffer, QUERY_GATEWAY_CMD) != NULL) {
olympux 23:47ee805435b1 524 udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
olympux 23:47ee805435b1 525 } // NNIOGW
olympux 23:47ee805435b1 526 else if (strstr(udp_receiving_buffer, QUERY_MAC_CMD) != NULL) {
olympux 23:47ee805435b1 527 udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
olympux 23:47ee805435b1 528 } // NNIOMC
olympux 23:47ee805435b1 529 // ask for TCP server port
olympux 23:47ee805435b1 530 else if (strstr(udp_receiving_buffer, QUERY_TCP_PORT_CMD) != NULL) {
olympux 23:47ee805435b1 531 char port[5];
olympux 23:47ee805435b1 532 sprintf(port, "%5d", tcp_server_local_port);
olympux 23:47ee805435b1 533 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 23:47ee805435b1 534 } // NNIOTP
olympux 23:47ee805435b1 535 // ask for UDP server port
olympux 23:47ee805435b1 536 else if (strstr(udp_receiving_buffer, QUERY_UDP_PORT_CMD) != NULL) {
olympux 23:47ee805435b1 537 char port[5];
olympux 23:47ee805435b1 538 sprintf(port, "%5d", udp_server_local_port);
olympux 23:47ee805435b1 539 udp_server.sendTo(ep_udp_client, port, strlen(port));
olympux 23:47ee805435b1 540 } // NNIOUP
olympux 23:47ee805435b1 541 else if (strstr(udp_receiving_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
olympux 23:47ee805435b1 542 #ifdef NTP
olympux 23:47ee805435b1 543 char str_time[50];
olympux 20:71c7950fdd91 544
olympux 23:47ee805435b1 545 DBG("Trying to update time...");
olympux 23:47ee805435b1 546 if (ntp.setTime("0.pool.ntp.org") == 0) {
olympux 23:47ee805435b1 547 DBG("Set time successfully");
olympux 23:47ee805435b1 548 time_t ctTime;
olympux 23:47ee805435b1 549 ctTime = time(NULL);
olympux 23:47ee805435b1 550
olympux 23:47ee805435b1 551 DBG("Time is set to (UTC): %s", ctime(&ctTime));
olympux 23:47ee805435b1 552 sprintf(str_time, "%s", ctime(&ctTime));
olympux 23:47ee805435b1 553 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 23:47ee805435b1 554 }
olympux 23:47ee805435b1 555 else {
olympux 23:47ee805435b1 556 WARN("Error");
olympux 23:47ee805435b1 557 sprintf(str_time, "ERR");
olympux 23:47ee805435b1 558 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 23:47ee805435b1 559 }
olympux 23:47ee805435b1 560 #elif
olympux 23:47ee805435b1 561 WARN("NTP disabled");
olympux 23:47ee805435b1 562 sprintf(str_time, "DIS");
olympux 20:71c7950fdd91 563 udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
olympux 23:47ee805435b1 564 #endif
olympux 23:47ee805435b1 565 } // NNIOTM
olympux 23:47ee805435b1 566
olympux 20:71c7950fdd91 567 break;
olympux 23:47ee805435b1 568 // length = 19, SET NETWORK CONFIGURATION
olympux 23:47ee805435b1 569 // Format: 4E 4E 49 4F C0 A8 00 78 FF FF FF 00 C0 A8 00 01 00 00 01
olympux 23:47ee805435b1 570 // (NNIO; IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
olympux 23:47ee805435b1 571 case SET_NETWORK_CONFIG_CMD_LENGTH: {
olympux 23:47ee805435b1 572 // check device id
olympux 23:47ee805435b1 573 char* id = strstr(udp_receiving_buffer, DEVICE_ID);
olympux 23:47ee805435b1 574 if (id == NULL)
olympux 23:47ee805435b1 575 break;
olympux 23:47ee805435b1 576 else if ((id - udp_receiving_buffer) > 0)
olympux 23:47ee805435b1 577 break;
olympux 23:47ee805435b1 578
olympux 23:47ee805435b1 579 DBG("Received user configuration");
olympux 23:47ee805435b1 580 write_eeprom_network(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
olympux 20:71c7950fdd91 581 break;
olympux 23:47ee805435b1 582 }
olympux 23:47ee805435b1 583 // length = 12, SET TCP SERVER CONFIGURATION
olympux 23:47ee805435b1 584 // auto update & its time period, TCP server configuration (IP & port)
olympux 23:47ee805435b1 585 // Format: 4E 4E 49 4F 'Y' 01 C0 A8 00 09 E0 2E (LSB MSB)
olympux 23:47ee805435b1 586 // NNIO Auto 1s 192.168.0.9 12000
olympux 23:47ee805435b1 587 case UPDATE_TCP_SERVER_INFO_CMD_LENGTH: {
olympux 23:47ee805435b1 588 char* id = strstr(udp_receiving_buffer, DEVICE_ID);
olympux 23:47ee805435b1 589 if (id == NULL)
olympux 23:47ee805435b1 590 break;
olympux 23:47ee805435b1 591 else if ((id - udp_receiving_buffer) > 0)
olympux 23:47ee805435b1 592 break;
olympux 23:47ee805435b1 593
olympux 23:47ee805435b1 594 DBG("Received TCP server configuration");
olympux 23:47ee805435b1 595 write_eeprom_tcpserver(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
olympux 20:71c7950fdd91 596 break;
olympux 23:47ee805435b1 597 }
olympux 23:47ee805435b1 598 default:
olympux 20:71c7950fdd91 599 break;
olympux 23:47ee805435b1 600 } // switch (n), check configuration command length
olympux 23:47ee805435b1 601 } // if starts with NN, a config command
olympux 25:48dd18cc147c 602 else { // if not a command, check to see if it is a 6-byte data package
olympux 25:48dd18cc147c 603 // process 6-byte data package
olympux 23:47ee805435b1 604 }
olympux 15:edeb0aed160d 605
olympux 20:71c7950fdd91 606 // wait to receive new config command
olympux 20:71c7950fdd91 607 udp_server.set_blocking(true);
olympux 20:71c7950fdd91 608 n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
olympux 25:48dd18cc147c 609 } // while (n > 0): config commands processor
olympux 25:48dd18cc147c 610 } // if (config_mode_flag)
olympux 25:48dd18cc147c 611 else if (n > 0) { // process other data packages sent using UDP
olympux 25:48dd18cc147c 612 process_received_net_data(udp_receiving_buffer, n);
olympux 25:48dd18cc147c 613 }
olympux 3:972ed747474c 614 #endif
olympux 4:568c97f2a407 615 } // network processor
olympux 11:709f90a3b599 616 }
olympux 11:709f90a3b599 617
olympux 12:7c152c0ca4d8 618 /*
olympux 12:7c152c0ca4d8 619 * Update digital outputs following receiving frame from TCP client
olympux 12:7c152c0ca4d8 620 */
olympux 12:7c152c0ca4d8 621 void update_digital_outputs(char* buf) {
olympux 18:ca499a2e7da6 622 DBG("Digital outputs: %s", buf);
olympux 11:709f90a3b599 623
olympux 12:7c152c0ca4d8 624 dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 625 dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 626 dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 627 dout3 = (buf[3] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 628 dout4 = (buf[4] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 629 dout5 = (buf[5] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 630 dout6 = (buf[6] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 631 dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
olympux 12:7c152c0ca4d8 632 }
olympux 12:7c152c0ca4d8 633
olympux 12:7c152c0ca4d8 634 void update_sending_frame(char* buf) {
olympux 12:7c152c0ca4d8 635 memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_ID, 4); // device id
olympux 12:7c152c0ca4d8 636 memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
olympux 12:7c152c0ca4d8 637 memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4);
olympux 11:709f90a3b599 638
olympux 12:7c152c0ca4d8 639 buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 640 buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 641 buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 642 buf[SENDING_PROTOCOL_DI_POS+3] = (din3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 643 buf[SENDING_PROTOCOL_DI_POS+4] = (din4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 644 buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 645 buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 646 buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 647
olympux 12:7c152c0ca4d8 648 buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 649 buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 650 buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 651 buf[SENDING_PROTOCOL_DO_POS+3] = (dout3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 652 buf[SENDING_PROTOCOL_DO_POS+4] = (dout4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 653 buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 654 buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 12:7c152c0ca4d8 655 buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
olympux 11:709f90a3b599 656
olympux 15:edeb0aed160d 657 uint16_t val = ain0.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 658 memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB
olympux 15:edeb0aed160d 659 val = ain1.read_u16(); // 16-bits normalised
olympux 15:edeb0aed160d 660 memcpy(&buf[SENDING_PROTOCOL_AI1_POS], &val, 2); // LSB MSB
olympux 23:47ee805435b1 661 val = 0x1234;
olympux 15:edeb0aed160d 662 memcpy(&buf[SENDING_PROTOCOL_AO0_POS], &val, 2); // LSB MSB
olympux 23:47ee805435b1 663 val = 0x5678;
olympux 15:edeb0aed160d 664 memcpy(&buf[SENDING_PROTOCOL_AO1_POS], &val, 2); // LSB MSB
olympux 12:7c152c0ca4d8 665 buf[SENDING_PROTOCOL_CR_POS] = 0x0D;
olympux 12:7c152c0ca4d8 666 buf[SENDING_PROTOCOL_CR_POS+1] = '\0';
olympux 4:568c97f2a407 667 }