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
main.cpp@39:083cf93121a9, 2016-06-14 (annotated)
- Committer:
- olympux
- Date:
- Tue Jun 14 21:25:04 2016 +0000
- Revision:
- 39:083cf93121a9
- Parent:
- 38:f8735ae519aa
- Child:
- 40:c966abbe2d62
New features; ; - Set current time; - Set on/off time for DigitalOut 0 and 1; - Auto on/off do0, do1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
olympux | 0:c2eac797face | 1 | /* |
olympux | 30:15e23257e786 | 2 | * Firmware supports NNIO and RPC protocols |
olympux | 30:15e23257e786 | 3 | */ |
olympux | 0:c2eac797face | 4 | #include "mbed.h" |
olympux | 27:22f289beceb8 | 5 | #include "rtos.h" |
olympux | 27:22f289beceb8 | 6 | #include "mbed_rpc.h" |
olympux | 27:22f289beceb8 | 7 | #include "Arguments.h" |
olympux | 27:22f289beceb8 | 8 | |
olympux | 12:7c152c0ca4d8 | 9 | #include "eeprom.h" |
olympux | 0:c2eac797face | 10 | #include "EthernetInterface.h" |
olympux | 9:d2534ecf88c6 | 11 | #include "NTPClient.h" |
olympux | 0:c2eac797face | 12 | |
olympux | 12:7c152c0ca4d8 | 13 | #include "my_eeprom_funcs.h" |
olympux | 20:71c7950fdd91 | 14 | #include "Watchdog.h" |
olympux | 12:7c152c0ca4d8 | 15 | |
olympux | 0:c2eac797face | 16 | |
olympux | 31:2e4b6de6c2f3 | 17 | /** Debug option |
olympux | 31:2e4b6de6c2f3 | 18 | * |
olympux | 31:2e4b6de6c2f3 | 19 | */ |
olympux | 25:48dd18cc147c | 20 | #if 1 |
olympux | 16:84a5bf7285d0 | 21 | //Enable debug |
olympux | 16:84a5bf7285d0 | 22 | #include <cstdio> |
olympux | 31:2e4b6de6c2f3 | 23 | #define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__); |
olympux | 31:2e4b6de6c2f3 | 24 | #define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__); |
olympux | 31:2e4b6de6c2f3 | 25 | #define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__); |
olympux | 16:84a5bf7285d0 | 26 | #else |
olympux | 16:84a5bf7285d0 | 27 | //Disable debug |
olympux | 31:2e4b6de6c2f3 | 28 | #define DBG(x, ...) |
olympux | 16:84a5bf7285d0 | 29 | #define WARN(x, ...) |
olympux | 31:2e4b6de6c2f3 | 30 | #define ERR(x, ...) |
olympux | 16:84a5bf7285d0 | 31 | #endif |
olympux | 16:84a5bf7285d0 | 32 | |
olympux | 16:84a5bf7285d0 | 33 | |
olympux | 2:18f10e7209f4 | 34 | /* |
olympux | 2:18f10e7209f4 | 35 | * Hardware defines |
olympux | 0:c2eac797face | 36 | */ |
olympux | 9:d2534ecf88c6 | 37 | // Ethernet |
olympux | 0:c2eac797face | 38 | SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk |
olympux | 11:709f90a3b599 | 39 | EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset |
olympux | 30:15e23257e786 | 40 | |
olympux | 30:15e23257e786 | 41 | /* |
olympux | 30:15e23257e786 | 42 | * EEPROM section |
olympux | 30:15e23257e786 | 43 | */ |
olympux | 30:15e23257e786 | 44 | // Virtual address defined by the user: 0xFFFF value is prohibited |
olympux | 30:15e23257e786 | 45 | uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr |
olympux | 30:15e23257e786 | 46 | 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet |
olympux | 30:15e23257e786 | 47 | 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway |
olympux | 30:15e23257e786 | 48 | 0x4212, // TCP server port, not used |
olympux | 30:15e23257e786 | 49 | 0x5212, // UDP server port, not used |
olympux | 30:15e23257e786 | 50 | 0x8888, // 1st run? 0xA5A5 = configured |
olympux | 30:15e23257e786 | 51 | 0x6212, 0x6313, 0x6414, // MAC |
olympux | 31:2e4b6de6c2f3 | 52 | |
olympux | 30:15e23257e786 | 53 | // this section is for the TCP server that this device connects to in TCP client mode |
olympux | 30:15e23257e786 | 54 | 0x7212, 0x7313, // 0xA5A5 = auto transmit status, time period |
olympux | 30:15e23257e786 | 55 | 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address |
olympux | 30:15e23257e786 | 56 | 0x9212, // TCP server port |
olympux | 31:2e4b6de6c2f3 | 57 | |
olympux | 30:15e23257e786 | 58 | // this section is for selecting protocol, not used |
olympux | 30:15e23257e786 | 59 | 0xA212, // 0xA5A5 = enable TCP server |
olympux | 30:15e23257e786 | 60 | 0xA313, // 0xA5A5 = eanble TCP client |
olympux | 30:15e23257e786 | 61 | 0xA414 // 0xA5A5 = enable UDP server |
olympux | 31:2e4b6de6c2f3 | 62 | }; |
olympux | 31:2e4b6de6c2f3 | 63 | |
olympux | 30:15e23257e786 | 64 | |
olympux | 30:15e23257e786 | 65 | /* |
olympux | 30:15e23257e786 | 66 | * Network configuration |
olympux | 30:15e23257e786 | 67 | */ |
olympux | 30:15e23257e786 | 68 | #define TCP_SERVER |
olympux | 30:15e23257e786 | 69 | #define TCP_CLIENT |
olympux | 30:15e23257e786 | 70 | #define UDP_SERVER |
olympux | 30:15e23257e786 | 71 | //#define UDP_CLIENT |
olympux | 30:15e23257e786 | 72 | #define NTP |
olympux | 30:15e23257e786 | 73 | |
olympux | 30:15e23257e786 | 74 | #define TCP_SERVER_WAIT_CLIENT_TIMEOUT 200 // timeout for local tcp server wait for a remote client |
olympux | 30:15e23257e786 | 75 | #define TCP_SERVER_RECEIVE_TIMEOUT 2000 // timeout for local tcp server wait to receive from remote client |
olympux | 30:15e23257e786 | 76 | #define TCP_CLIENT_RECEIVE_TIMEOUT 200 // timeout for local tcp client try to connect remote server |
olympux | 30:15e23257e786 | 77 | #define UDP_SERVER_RECEIVE_TIMEOUT 100 // timeout for checking config command |
olympux | 30:15e23257e786 | 78 | |
olympux | 0:c2eac797face | 79 | |
olympux | 30:15e23257e786 | 80 | // TCP server function |
olympux | 30:15e23257e786 | 81 | TCPSocketServer tcp_server; |
olympux | 30:15e23257e786 | 82 | TCPSocketConnection tcp_client; |
olympux | 30:15e23257e786 | 83 | // TCP client function |
olympux | 30:15e23257e786 | 84 | TCPSocketConnection tcp_sock; |
olympux | 30:15e23257e786 | 85 | // UDP server |
olympux | 30:15e23257e786 | 86 | UDPSocket udp_server; |
olympux | 30:15e23257e786 | 87 | Endpoint ep_udp_client; |
olympux | 30:15e23257e786 | 88 | // NTP |
olympux | 30:15e23257e786 | 89 | NTPClient ntp; |
olympux | 30:15e23257e786 | 90 | |
olympux | 30:15e23257e786 | 91 | |
olympux | 30:15e23257e786 | 92 | /* |
olympux | 30:15e23257e786 | 93 | * Variables for network configuration, TCP server |
olympux | 30:15e23257e786 | 94 | */ |
olympux | 30:15e23257e786 | 95 | uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits |
olympux | 30:15e23257e786 | 96 | uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom |
olympux | 30:15e23257e786 | 97 | char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx |
olympux | 30:15e23257e786 | 98 | uint16_t configured_ip = 0; // static ip configured flag |
olympux | 30:15e23257e786 | 99 | |
olympux | 30:15e23257e786 | 100 | const uint16_t tcp_server_local_port = 10000; // fixed, change to 7000 if internet required |
olympux | 30:15e23257e786 | 101 | const uint16_t udp_server_local_port = 11000; // fixed |
olympux | 30:15e23257e786 | 102 | |
olympux | 30:15e23257e786 | 103 | // TCP client: this section is used for the TCP server that this device connects to in TCP client mode |
olympux | 30:15e23257e786 | 104 | // this device will transmit status every transmit_time_period |
olympux | 30:15e23257e786 | 105 | uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s |
olympux | 30:15e23257e786 | 106 | uint16_t u16server_ip_addr[4]; // directly loaded from eeprom |
olympux | 30:15e23257e786 | 107 | uint8_t u8server_ip_addr[4]; // server ip address in 8-bits |
olympux | 30:15e23257e786 | 108 | char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr |
olympux | 30:15e23257e786 | 109 | uint16_t u16tcp_server_port; // directly loaded from eeprom |
olympux | 30:15e23257e786 | 110 | uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server |
olympux | 30:15e23257e786 | 111 | |
olympux | 30:15e23257e786 | 112 | #define NET_BUF_LEN 256 |
olympux | 30:15e23257e786 | 113 | char tcp_receiving_buffer[NET_BUF_LEN]; |
olympux | 30:15e23257e786 | 114 | char udp_receiving_buffer[NET_BUF_LEN]; |
olympux | 31:2e4b6de6c2f3 | 115 | char network_output_buffer[NET_BUF_LEN]; // output buffer for TCP/UDP control command |
olympux | 30:15e23257e786 | 116 | |
olympux | 30:15e23257e786 | 117 | |
olympux | 30:15e23257e786 | 118 | /* |
olympux | 30:15e23257e786 | 119 | * RPC Protocol |
olympux | 30:15e23257e786 | 120 | * Use the RPC enabled wrapped class - see RpcClasses.h for more info |
olympux | 30:15e23257e786 | 121 | */ |
olympux | 27:22f289beceb8 | 122 | // DigitalIn |
olympux | 35:f5c98e2d6aad | 123 | RpcDigitalIn di0(PB_14, "di0"); |
olympux | 35:f5c98e2d6aad | 124 | RpcDigitalIn di1(PB_12, "di1"); |
olympux | 35:f5c98e2d6aad | 125 | RpcDigitalIn di2(PB_10, "di2"); |
olympux | 35:f5c98e2d6aad | 126 | RpcDigitalIn di3(PB_1, "di3"); |
olympux | 35:f5c98e2d6aad | 127 | RpcDigitalIn di4(PB_15, "di4"); |
olympux | 35:f5c98e2d6aad | 128 | RpcDigitalIn di5(PB_13, "di5"); |
olympux | 35:f5c98e2d6aad | 129 | RpcDigitalIn di6(PB_11, "di6"); |
olympux | 35:f5c98e2d6aad | 130 | RpcDigitalIn di7(PB_2, "di7"); |
olympux | 11:709f90a3b599 | 131 | DigitalIn din0(PB_14); |
olympux | 11:709f90a3b599 | 132 | DigitalIn din1(PB_12); |
olympux | 11:709f90a3b599 | 133 | DigitalIn din2(PB_10); |
olympux | 11:709f90a3b599 | 134 | DigitalIn din3(PB_1); |
olympux | 11:709f90a3b599 | 135 | DigitalIn din4(PB_15); |
olympux | 11:709f90a3b599 | 136 | DigitalIn din5(PB_13); |
olympux | 11:709f90a3b599 | 137 | DigitalIn din6(PB_11); |
olympux | 11:709f90a3b599 | 138 | DigitalIn din7(PB_2); |
olympux | 27:22f289beceb8 | 139 | // DigitalOut |
olympux | 35:f5c98e2d6aad | 140 | RpcDigitalOut do0(PB_3, "do0"); |
olympux | 35:f5c98e2d6aad | 141 | RpcDigitalOut do1(PB_5, "do1"); |
olympux | 35:f5c98e2d6aad | 142 | RpcDigitalOut do2(PB_7, "do2"); |
olympux | 35:f5c98e2d6aad | 143 | RpcDigitalOut do3(PB_9, "do3"); |
olympux | 35:f5c98e2d6aad | 144 | RpcDigitalOut do4(PD_2, "do4"); |
olympux | 35:f5c98e2d6aad | 145 | RpcDigitalOut do5(PB_4, "do5"); |
olympux | 35:f5c98e2d6aad | 146 | RpcDigitalOut do6(PB_6, "do6"); |
olympux | 35:f5c98e2d6aad | 147 | RpcDigitalOut do7(PB_8, "do7"); |
olympux | 11:709f90a3b599 | 148 | DigitalOut dout0(PB_3); |
olympux | 11:709f90a3b599 | 149 | DigitalOut dout1(PB_5); |
olympux | 11:709f90a3b599 | 150 | DigitalOut dout2(PB_7); |
olympux | 11:709f90a3b599 | 151 | DigitalOut dout3(PB_9); |
olympux | 11:709f90a3b599 | 152 | DigitalOut dout4(PD_2); |
olympux | 11:709f90a3b599 | 153 | DigitalOut dout5(PB_4); |
olympux | 11:709f90a3b599 | 154 | DigitalOut dout6(PB_6); |
olympux | 11:709f90a3b599 | 155 | DigitalOut dout7(PB_8); |
olympux | 27:22f289beceb8 | 156 | // AnalogIn |
olympux | 35:f5c98e2d6aad | 157 | RpcAnalogIn adc10(PC_0, "ai0"); // adc10 |
olympux | 35:f5c98e2d6aad | 158 | RpcAnalogIn adc11(PC_1, "ai1"); // adc11 |
olympux | 11:709f90a3b599 | 159 | AnalogIn ain0(PC_0); |
olympux | 11:709f90a3b599 | 160 | AnalogIn ain1(PC_1); |
olympux | 27:22f289beceb8 | 161 | // AnalogOut, PWM |
olympux | 27:22f289beceb8 | 162 | RpcPwmOut pwm11(PA_8, "pwm0"); // pwm11 |
olympux | 27:22f289beceb8 | 163 | RpcPwmOut pwm21(PA_15, "pwm1"); // pwm21 |
olympux | 27:22f289beceb8 | 164 | // Serial |
olympux | 27:22f289beceb8 | 165 | RpcSerial usart2(USBTX, USBRX, "uart"); // usart2 |
olympux | 27:22f289beceb8 | 166 | Serial uart(USBTX,USBRX); |
olympux | 27:22f289beceb8 | 167 | // Timer |
olympux | 35:f5c98e2d6aad | 168 | RpcTimer timer1("tmr1"); |
olympux | 20:71c7950fdd91 | 169 | // Watchdog |
olympux | 20:71c7950fdd91 | 170 | Watchdog wdt; |
olympux | 20:71c7950fdd91 | 171 | |
olympux | 39:083cf93121a9 | 172 | |
olympux | 39:083cf93121a9 | 173 | // Some variable types that can be modified through RPC. |
olympux | 39:083cf93121a9 | 174 | //int wheelsOn; |
olympux | 39:083cf93121a9 | 175 | //char lcdBannerMessage; |
olympux | 39:083cf93121a9 | 176 | //float speed; |
olympux | 39:083cf93121a9 | 177 | int current_time; |
olympux | 39:083cf93121a9 | 178 | int do0OnTime, do0OffTime; |
olympux | 39:083cf93121a9 | 179 | int do1OnTime, do1OffTime; |
olympux | 39:083cf93121a9 | 180 | |
olympux | 39:083cf93121a9 | 181 | //RPCVariable<int> rpcLights(&wheelsOn, "wheels"); |
olympux | 39:083cf93121a9 | 182 | //RPCVariable<char> rpcBanner(&lcdBannerMessage, "banner"); |
olympux | 39:083cf93121a9 | 183 | //RPCVariable<float> rpcSpeed(&speed, "speed"); |
olympux | 39:083cf93121a9 | 184 | RPCVariable<int> rpcCurrentTime(¤t_time, "Time"); |
olympux | 39:083cf93121a9 | 185 | RPCVariable<int> rpcdo0OnTime(&do0OnTime, "do0OnTime"); |
olympux | 39:083cf93121a9 | 186 | RPCVariable<int> rpcdo0OffTime(&do0OffTime, "do0OffTime"); |
olympux | 39:083cf93121a9 | 187 | RPCVariable<int> rpcdo1OnTime(&do0OnTime, "do1OnTime"); |
olympux | 39:083cf93121a9 | 188 | RPCVariable<int> rpcdo1OffTime(&do0OffTime, "do1OffTime"); |
olympux | 39:083cf93121a9 | 189 | |
olympux | 39:083cf93121a9 | 190 | // RPC function definitions |
olympux | 39:083cf93121a9 | 191 | // Create a function of the required format |
olympux | 39:083cf93121a9 | 192 | void set_current_time(Arguments* args, Reply* rep); |
olympux | 39:083cf93121a9 | 193 | void set_current_time(Arguments* args, Reply* rep){ |
olympux | 39:083cf93121a9 | 194 | time_t ct = (time_t)current_time; // convert |
olympux | 39:083cf93121a9 | 195 | struct tm *st = localtime(&ct); |
olympux | 39:083cf93121a9 | 196 | |
olympux | 39:083cf93121a9 | 197 | set_time(ct); // set time |
olympux | 39:083cf93121a9 | 198 | |
olympux | 39:083cf93121a9 | 199 | DBG("Set current time to: %s", ctime(&ct)); |
olympux | 39:083cf93121a9 | 200 | DBG("Time only: %d:%d:%d", st->tm_hour, st->tm_min, st->tm_sec); |
olympux | 39:083cf93121a9 | 201 | } |
olympux | 39:083cf93121a9 | 202 | // Attach it to an RPC object |
olympux | 39:083cf93121a9 | 203 | RPCFunction rpcSetCurrentTime(&set_current_time, "SetTime"); |
olympux | 39:083cf93121a9 | 204 | |
olympux | 13:bcf840da68fd | 205 | /* |
olympux | 30:15e23257e786 | 206 | * NNIO Protocol |
olympux | 30:15e23257e786 | 207 | */ |
olympux | 9:d2534ecf88c6 | 208 | // Commands |
olympux | 29:bc052f283ada | 209 | #define DEVICE_DESCRIPTION "NNIO" |
olympux | 27:22f289beceb8 | 210 | #define DEVICE_CONFIG_CODE "NNCF" |
olympux | 27:22f289beceb8 | 211 | #define DEVICE_CONTROL_CODE "NNIO" |
olympux | 17:88ef7a078095 | 212 | |
olympux | 17:88ef7a078095 | 213 | #define RECEIVING_PROTOCOL_LENGTH 58 |
olympux | 17:88ef7a078095 | 214 | #define SENDING_PROTOCOL_LENGTH 39 |
olympux | 26:09e0dd020900 | 215 | #define QUERY_NETWORK_CONFIG_CMD_LENGTH 6 |
olympux | 17:88ef7a078095 | 216 | #define SET_NETWORK_CONFIG_CMD_LENGTH 19 |
olympux | 26:09e0dd020900 | 217 | #define UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH 12 |
olympux | 17:88ef7a078095 | 218 | |
olympux | 27:22f289beceb8 | 219 | #define QUERY_DISCOVERY_CMD "NNCFDS" |
olympux | 27:22f289beceb8 | 220 | #define QUERY_IP_CMD "NNCFIP" |
olympux | 27:22f289beceb8 | 221 | #define QUERY_SUBNET_CMD "NNCFSN" |
olympux | 27:22f289beceb8 | 222 | #define QUERY_GATEWAY_CMD "NNCFGW" |
olympux | 27:22f289beceb8 | 223 | #define QUERY_MAC_CMD "NNCFMC" |
olympux | 27:22f289beceb8 | 224 | #define QUERY_UDP_PORT_CMD "NNCFUP" |
olympux | 27:22f289beceb8 | 225 | #define QUERY_TCP_PORT_CMD "NNCFTP" |
olympux | 27:22f289beceb8 | 226 | #define QUERY_UPDATE_TIME_CMD "NNCFTM" |
olympux | 11:709f90a3b599 | 227 | #define RECEIVING_PROTOCOL_ENABLE_OUTPUT 'O' |
olympux | 11:709f90a3b599 | 228 | #define QUERY_STATUS_COMMAND 'Q' |
olympux | 11:709f90a3b599 | 229 | #define DIGITAL_HIGH 'H' |
olympux | 11:709f90a3b599 | 230 | #define DIGITAL_LOW 'L' |
olympux | 9:d2534ecf88c6 | 231 | |
olympux | 9:d2534ecf88c6 | 232 | |
olympux | 9:d2534ecf88c6 | 233 | // Positions |
olympux | 11:709f90a3b599 | 234 | #define RECEIVING_PROTOCOL_ID_POS 0 |
olympux | 9:d2534ecf88c6 | 235 | #define RECEIVING_PROTOCOL_OP_POS 4 |
olympux | 9:d2534ecf88c6 | 236 | #define RECEIVING_PROTOCOL_EN_DO_POS RECEIVING_PROTOCOL_OP_POS + 0 |
olympux | 9:d2534ecf88c6 | 237 | #define RECEIVING_PROTOCOL_EN_A0O_POS RECEIVING_PROTOCOL_OP_POS + 1 |
olympux | 9:d2534ecf88c6 | 238 | #define RECEIVING_PROTOCOL_EN_A1O_POS RECEIVING_PROTOCOL_OP_POS + 2 |
olympux | 9:d2534ecf88c6 | 239 | #define RECEIVING_PROTOCOL_EN_UART_POS RECEIVING_PROTOCOL_OP_POS + 3 |
olympux | 9:d2534ecf88c6 | 240 | #define RECEIVING_PROTOCOL_COMMAND_POS RECEIVING_PROTOCOL_OP_POS + 4 |
olympux | 11:709f90a3b599 | 241 | |
olympux | 11:709f90a3b599 | 242 | #define RECEIVING_PROTOCOL_IP_POS 9 |
olympux | 11:709f90a3b599 | 243 | #define RECEIVING_PROTOCOL_DO_POS 13 |
olympux | 11:709f90a3b599 | 244 | #define RECEIVING_PROTOCOL_A0O_POS 21 |
olympux | 11:709f90a3b599 | 245 | #define RECEIVING_PROTOCOL_A01_POS 23 |
olympux | 11:709f90a3b599 | 246 | #define RECEIVING_PROTOCOL_UART_POS 25 |
olympux | 9:d2534ecf88c6 | 247 | |
olympux | 9:d2534ecf88c6 | 248 | |
olympux | 11:709f90a3b599 | 249 | #define SENDING_PROTOCOL_ID_POS 0 |
olympux | 11:709f90a3b599 | 250 | #define SENDING_PROTOCOL_MAC_POS 4 |
olympux | 11:709f90a3b599 | 251 | #define SENDING_PROTOCOL_IP_POS 10 |
olympux | 11:709f90a3b599 | 252 | #define SENDING_PROTOCOL_DI_POS 14 |
olympux | 11:709f90a3b599 | 253 | #define SENDING_PROTOCOL_DO_POS 22 |
olympux | 11:709f90a3b599 | 254 | #define SENDING_PROTOCOL_AI0_POS 30 |
olympux | 11:709f90a3b599 | 255 | #define SENDING_PROTOCOL_AI1_POS 32 |
olympux | 11:709f90a3b599 | 256 | #define SENDING_PROTOCOL_AO0_POS 34 |
olympux | 11:709f90a3b599 | 257 | #define SENDING_PROTOCOL_AO1_POS 36 |
olympux | 11:709f90a3b599 | 258 | #define SENDING_PROTOCOL_CR_POS 38 |
olympux | 0:c2eac797face | 259 | |
olympux | 2:18f10e7209f4 | 260 | |
olympux | 2:18f10e7209f4 | 261 | /* |
olympux | 2:18f10e7209f4 | 262 | * RTOS |
olympux | 2:18f10e7209f4 | 263 | */ |
olympux | 2:18f10e7209f4 | 264 | struct message_t { |
olympux | 2:18f10e7209f4 | 265 | int len; |
olympux | 2:18f10e7209f4 | 266 | char *msg; |
olympux | 2:18f10e7209f4 | 267 | }; |
olympux | 3:972ed747474c | 268 | Queue<message_t, 16> uart_queue; |
olympux | 15:edeb0aed160d | 269 | Queue<bool, 1> auto_update_queue; |
olympux | 2:18f10e7209f4 | 270 | |
olympux | 2:18f10e7209f4 | 271 | |
olympux | 26:09e0dd020900 | 272 | |
olympux | 26:09e0dd020900 | 273 | // Prototypes |
olympux | 26:09e0dd020900 | 274 | int ethernet_init(void); |
olympux | 28:00c0c20d03c1 | 275 | int process_control_command(char* received_buffer, int len); |
olympux | 26:09e0dd020900 | 276 | void process_config_command(char* received_buffer, int len); |
olympux | 26:09e0dd020900 | 277 | void update_digital_outputs(char* buf); |
olympux | 26:09e0dd020900 | 278 | void update_sending_frame(char* buf); |
olympux | 26:09e0dd020900 | 279 | |
olympux | 26:09e0dd020900 | 280 | |
olympux | 2:18f10e7209f4 | 281 | /* |
olympux | 2:18f10e7209f4 | 282 | * Threads |
olympux | 2:18f10e7209f4 | 283 | */ |
olympux | 31:2e4b6de6c2f3 | 284 | // Timer thread for auto update in TCP client function |
olympux | 31:2e4b6de6c2f3 | 285 | void auto_update_timer_thread(void const* args) |
olympux | 31:2e4b6de6c2f3 | 286 | { |
olympux | 18:ca499a2e7da6 | 287 | bool update_flag = true; |
olympux | 31:2e4b6de6c2f3 | 288 | |
olympux | 15:edeb0aed160d | 289 | Thread::wait(500); |
olympux | 15:edeb0aed160d | 290 | while(true) { |
olympux | 15:edeb0aed160d | 291 | auto_update_queue.put(&update_flag); |
olympux | 18:ca499a2e7da6 | 292 | Thread::wait(1000*transmit_time_period); // Thread::wait() in ms |
olympux | 15:edeb0aed160d | 293 | } |
olympux | 15:edeb0aed160d | 294 | } |
olympux | 15:edeb0aed160d | 295 | |
olympux | 15:edeb0aed160d | 296 | |
olympux | 20:71c7950fdd91 | 297 | // WDT reset |
olympux | 31:2e4b6de6c2f3 | 298 | void wdt_reset_thread(void const* args) |
olympux | 31:2e4b6de6c2f3 | 299 | { |
olympux | 20:71c7950fdd91 | 300 | while (true) |
olympux | 20:71c7950fdd91 | 301 | wdt.Service(); |
olympux | 20:71c7950fdd91 | 302 | } |
olympux | 20:71c7950fdd91 | 303 | |
olympux | 39:083cf93121a9 | 304 | // Timer thread to check on/off time |
olympux | 39:083cf93121a9 | 305 | void digital_outputs_timer_thread(void const* args) |
olympux | 39:083cf93121a9 | 306 | { |
olympux | 39:083cf93121a9 | 307 | Thread::wait(700); |
olympux | 39:083cf93121a9 | 308 | |
olympux | 39:083cf93121a9 | 309 | while(true) { |
olympux | 39:083cf93121a9 | 310 | // read current time |
olympux | 39:083cf93121a9 | 311 | time_t seconds = time(NULL); |
olympux | 39:083cf93121a9 | 312 | struct tm *st = localtime(&seconds); |
olympux | 39:083cf93121a9 | 313 | int current_time_in_seconds = 3600*(st->tm_hour) + 60*(st->tm_min) + st->tm_sec; |
olympux | 39:083cf93121a9 | 314 | DBG("Current time: %d:%d:%d", st->tm_hour, st->tm_min, st->tm_sec); |
olympux | 39:083cf93121a9 | 315 | |
olympux | 39:083cf93121a9 | 316 | // check do0 |
olympux | 39:083cf93121a9 | 317 | if (do0OnTime < do0OffTime) { |
olympux | 39:083cf93121a9 | 318 | if ((current_time_in_seconds >= do0OnTime) && (current_time_in_seconds < do0OffTime)){ |
olympux | 39:083cf93121a9 | 319 | if (dout0 == 0) { |
olympux | 39:083cf93121a9 | 320 | dout0 = 1; |
olympux | 39:083cf93121a9 | 321 | DBG("do0 ON"); |
olympux | 39:083cf93121a9 | 322 | } |
olympux | 39:083cf93121a9 | 323 | else { |
olympux | 39:083cf93121a9 | 324 | DBG("do0 ON'ed"); |
olympux | 39:083cf93121a9 | 325 | } |
olympux | 39:083cf93121a9 | 326 | } |
olympux | 39:083cf93121a9 | 327 | else { |
olympux | 39:083cf93121a9 | 328 | if (dout0 == 1) { |
olympux | 39:083cf93121a9 | 329 | dout0 = 0; |
olympux | 39:083cf93121a9 | 330 | DBG("do0 OFF'ed"); |
olympux | 39:083cf93121a9 | 331 | } |
olympux | 39:083cf93121a9 | 332 | else { |
olympux | 39:083cf93121a9 | 333 | DBG("do0 OFF"); |
olympux | 39:083cf93121a9 | 334 | } |
olympux | 39:083cf93121a9 | 335 | } |
olympux | 39:083cf93121a9 | 336 | } |
olympux | 39:083cf93121a9 | 337 | else { |
olympux | 39:083cf93121a9 | 338 | if ((current_time_in_seconds >= do0OffTime) && ((current_time_in_seconds < do0OnTime))) { |
olympux | 39:083cf93121a9 | 339 | if (dout0 == 1) { |
olympux | 39:083cf93121a9 | 340 | dout0 = 0; |
olympux | 39:083cf93121a9 | 341 | DBG("do0 OFF"); |
olympux | 39:083cf93121a9 | 342 | } |
olympux | 39:083cf93121a9 | 343 | else { |
olympux | 39:083cf93121a9 | 344 | DBG("do0 OFF'ed"); |
olympux | 39:083cf93121a9 | 345 | } |
olympux | 39:083cf93121a9 | 346 | } |
olympux | 39:083cf93121a9 | 347 | else { |
olympux | 39:083cf93121a9 | 348 | if (dout0 == 0) { |
olympux | 39:083cf93121a9 | 349 | dout0 = 1; |
olympux | 39:083cf93121a9 | 350 | DBG("do0 ON"); |
olympux | 39:083cf93121a9 | 351 | } |
olympux | 39:083cf93121a9 | 352 | else { |
olympux | 39:083cf93121a9 | 353 | DBG("do0 ON'ed"); |
olympux | 39:083cf93121a9 | 354 | } |
olympux | 39:083cf93121a9 | 355 | } |
olympux | 39:083cf93121a9 | 356 | } |
olympux | 39:083cf93121a9 | 357 | |
olympux | 39:083cf93121a9 | 358 | // check do1 |
olympux | 39:083cf93121a9 | 359 | if (do1OnTime < do1OffTime) { |
olympux | 39:083cf93121a9 | 360 | if ((current_time_in_seconds >= do1OnTime) && (current_time_in_seconds < do1OffTime)){ |
olympux | 39:083cf93121a9 | 361 | if (dout1 == 0) { |
olympux | 39:083cf93121a9 | 362 | dout1 = 1; |
olympux | 39:083cf93121a9 | 363 | DBG("do1 ON"); |
olympux | 39:083cf93121a9 | 364 | } |
olympux | 39:083cf93121a9 | 365 | else { |
olympux | 39:083cf93121a9 | 366 | DBG("do1 ON'ed"); |
olympux | 39:083cf93121a9 | 367 | } |
olympux | 39:083cf93121a9 | 368 | } |
olympux | 39:083cf93121a9 | 369 | else { |
olympux | 39:083cf93121a9 | 370 | if (dout1 == 1) { |
olympux | 39:083cf93121a9 | 371 | dout1 = 0; |
olympux | 39:083cf93121a9 | 372 | DBG("do1 OFF"); |
olympux | 39:083cf93121a9 | 373 | } |
olympux | 39:083cf93121a9 | 374 | else { |
olympux | 39:083cf93121a9 | 375 | DBG("do1 OFF'ed"); |
olympux | 39:083cf93121a9 | 376 | } |
olympux | 39:083cf93121a9 | 377 | } |
olympux | 39:083cf93121a9 | 378 | } |
olympux | 39:083cf93121a9 | 379 | else { |
olympux | 39:083cf93121a9 | 380 | if ((current_time_in_seconds >= do1OffTime) && ((current_time_in_seconds < do1OnTime))) { |
olympux | 39:083cf93121a9 | 381 | if (dout1 == 1) { |
olympux | 39:083cf93121a9 | 382 | dout1 = 0; |
olympux | 39:083cf93121a9 | 383 | DBG("do1 OFF"); |
olympux | 39:083cf93121a9 | 384 | } |
olympux | 39:083cf93121a9 | 385 | else { |
olympux | 39:083cf93121a9 | 386 | DBG("do1 OFF'ed"); |
olympux | 39:083cf93121a9 | 387 | } |
olympux | 39:083cf93121a9 | 388 | } |
olympux | 39:083cf93121a9 | 389 | else { |
olympux | 39:083cf93121a9 | 390 | if (dout1 == 0) { |
olympux | 39:083cf93121a9 | 391 | dout1 = 1; |
olympux | 39:083cf93121a9 | 392 | DBG("do1 ON"); |
olympux | 39:083cf93121a9 | 393 | } |
olympux | 39:083cf93121a9 | 394 | else { |
olympux | 39:083cf93121a9 | 395 | DBG("do1 ON'ed"); |
olympux | 39:083cf93121a9 | 396 | } |
olympux | 39:083cf93121a9 | 397 | } |
olympux | 39:083cf93121a9 | 398 | } |
olympux | 39:083cf93121a9 | 399 | // wait 1s |
olympux | 39:083cf93121a9 | 400 | Thread::wait(10000); // Thread::wait() in ms |
olympux | 39:083cf93121a9 | 401 | } |
olympux | 38:f8735ae519aa | 402 | } |
olympux | 38:f8735ae519aa | 403 | |
olympux | 38:f8735ae519aa | 404 | // Main code |
olympux | 4:568c97f2a407 | 405 | int main() |
olympux | 4:568c97f2a407 | 406 | { |
olympux | 9:d2534ecf88c6 | 407 | int n, ret; |
olympux | 31:2e4b6de6c2f3 | 408 | |
olympux | 20:71c7950fdd91 | 409 | Thread::wait(500); // turn on delay |
olympux | 31:2e4b6de6c2f3 | 410 | |
olympux | 4:568c97f2a407 | 411 | /* |
olympux | 9:d2534ecf88c6 | 412 | * Configure |
olympux | 4:568c97f2a407 | 413 | */ |
olympux | 11:709f90a3b599 | 414 | uart.baud(115200); |
olympux | 36:dc6f079777bb | 415 | DBG("Starting..."); |
olympux | 31:2e4b6de6c2f3 | 416 | |
olympux | 31:2e4b6de6c2f3 | 417 | // check watchdog |
olympux | 20:71c7950fdd91 | 418 | if (wdt.WatchdogCausedReset()) |
olympux | 20:71c7950fdd91 | 419 | DBG("Watchdog caused reset."); |
olympux | 20:71c7950fdd91 | 420 | wdt.Configure(4); |
olympux | 31:2e4b6de6c2f3 | 421 | |
olympux | 6:d054e394fba3 | 422 | /* |
olympux | 6:d054e394fba3 | 423 | * FLASH |
olympux | 6:d054e394fba3 | 424 | */ |
olympux | 12:7c152c0ca4d8 | 425 | load_eeprom_network(); |
olympux | 15:edeb0aed160d | 426 | load_eeprom_tcpserver(); |
olympux | 31:2e4b6de6c2f3 | 427 | |
olympux | 20:71c7950fdd91 | 428 | /* |
olympux | 20:71c7950fdd91 | 429 | * UI threads |
olympux | 20:71c7950fdd91 | 430 | */ |
olympux | 33:c906ccc220ba | 431 | Thread t2(auto_update_timer_thread); |
olympux | 20:71c7950fdd91 | 432 | Thread t3(wdt_reset_thread); |
olympux | 39:083cf93121a9 | 433 | Thread t4(digital_outputs_timer_thread); |
olympux | 31:2e4b6de6c2f3 | 434 | |
olympux | 4:568c97f2a407 | 435 | /* |
olympux | 4:568c97f2a407 | 436 | * Ethernet |
olympux | 4:568c97f2a407 | 437 | */ |
olympux | 6:d054e394fba3 | 438 | ret = ethernet_init(); |
olympux | 4:568c97f2a407 | 439 | if (ret) { |
olympux | 18:ca499a2e7da6 | 440 | ERR("Ethernet initialisation failed. App halted."); |
olympux | 4:568c97f2a407 | 441 | while (true) {}; |
olympux | 4:568c97f2a407 | 442 | } |
olympux | 31:2e4b6de6c2f3 | 443 | |
olympux | 23:47ee805435b1 | 444 | Thread::wait(2000); // TCP/UDP stack delay |
olympux | 12:7c152c0ca4d8 | 445 | |
olympux | 31:2e4b6de6c2f3 | 446 | /* |
olympux | 31:2e4b6de6c2f3 | 447 | * UDP server |
olympux | 31:2e4b6de6c2f3 | 448 | * TCP server/client |
olympux | 31:2e4b6de6c2f3 | 449 | */ |
olympux | 20:71c7950fdd91 | 450 | #ifdef UDP_SERVER |
olympux | 20:71c7950fdd91 | 451 | ret = udp_server.bind(udp_server_local_port); |
olympux | 20:71c7950fdd91 | 452 | DBG("UDP server started (sock.bind = %d)...", ret); |
olympux | 20:71c7950fdd91 | 453 | udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT); |
olympux | 20:71c7950fdd91 | 454 | #endif |
olympux | 20:71c7950fdd91 | 455 | |
olympux | 3:972ed747474c | 456 | #ifdef TCP_SERVER |
olympux | 12:7c152c0ca4d8 | 457 | tcp_server.bind(tcp_server_local_port); |
olympux | 3:972ed747474c | 458 | tcp_server.listen(); |
olympux | 18:ca499a2e7da6 | 459 | DBG("TCP server started..."); |
olympux | 4:568c97f2a407 | 460 | tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT); |
olympux | 3:972ed747474c | 461 | #endif |
olympux | 14:18eda020a589 | 462 | |
olympux | 14:18eda020a589 | 463 | #ifdef TCP_CLIENT |
olympux | 18:ca499a2e7da6 | 464 | |
olympux | 14:18eda020a589 | 465 | #endif |
olympux | 31:2e4b6de6c2f3 | 466 | |
olympux | 12:7c152c0ca4d8 | 467 | /* |
olympux | 19:05934ee9ee67 | 468 | * Network loop processor |
olympux | 12:7c152c0ca4d8 | 469 | */ |
olympux | 0:c2eac797face | 470 | while (true) { |
olympux | 30:15e23257e786 | 471 | #ifdef TCP_CLIENT // auto update device status to a remote TCP server |
olympux | 33:c906ccc220ba | 472 | if (auto_transmit_flag == DEFAULT_ENABLE_FLAG_VALUE) { |
olympux | 18:ca499a2e7da6 | 473 | // connect to TCP server if required |
olympux | 18:ca499a2e7da6 | 474 | if (!tcp_sock.is_connected()) { |
olympux | 20:71c7950fdd91 | 475 | ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port); // timeout is default in connect() in W5500.h |
olympux | 18:ca499a2e7da6 | 476 | if (ret > -1) { |
olympux | 18:ca499a2e7da6 | 477 | DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port); |
olympux | 31:2e4b6de6c2f3 | 478 | } else { |
olympux | 18:ca499a2e7da6 | 479 | ERR("Unable to connect to %s on port %d", str_server_ip_addr, u16tcp_server_port); |
olympux | 18:ca499a2e7da6 | 480 | } |
olympux | 16:84a5bf7285d0 | 481 | } |
olympux | 31:2e4b6de6c2f3 | 482 | |
olympux | 18:ca499a2e7da6 | 483 | // transmit data if connected |
olympux | 18:ca499a2e7da6 | 484 | if (tcp_sock.is_connected()) { |
olympux | 18:ca499a2e7da6 | 485 | osEvent evt = auto_update_queue.get(1); // timeout after 1ms |
olympux | 18:ca499a2e7da6 | 486 | if (evt.status == osEventMessage) { |
olympux | 18:ca499a2e7da6 | 487 | DBG("Updating..."); |
olympux | 31:2e4b6de6c2f3 | 488 | update_sending_frame(network_output_buffer); |
olympux | 31:2e4b6de6c2f3 | 489 | tcp_sock.send_all(network_output_buffer, SENDING_PROTOCOL_LENGTH); |
olympux | 19:05934ee9ee67 | 490 | } |
olympux | 31:2e4b6de6c2f3 | 491 | |
olympux | 19:05934ee9ee67 | 492 | // check to receive or timeout |
olympux | 19:05934ee9ee67 | 493 | tcp_sock.set_blocking(false, TCP_CLIENT_RECEIVE_TIMEOUT); |
olympux | 19:05934ee9ee67 | 494 | n = tcp_sock.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer)); |
olympux | 19:05934ee9ee67 | 495 | if (n > 0) { |
olympux | 19:05934ee9ee67 | 496 | // got some data, test it |
olympux | 19:05934ee9ee67 | 497 | DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer); |
olympux | 32:db2e8ea06ee1 | 498 | n = process_control_command(tcp_receiving_buffer, n); |
olympux | 32:db2e8ea06ee1 | 499 | // send reply back to client, NNIO protocol always returns 0 |
olympux | 32:db2e8ea06ee1 | 500 | // RPC-style protocol |
olympux | 32:db2e8ea06ee1 | 501 | if (n > 0) { |
olympux | 32:db2e8ea06ee1 | 502 | network_output_buffer[n] = '\0'; |
olympux | 32:db2e8ea06ee1 | 503 | tcp_sock.send_all(network_output_buffer, strlen(network_output_buffer)); |
olympux | 32:db2e8ea06ee1 | 504 | } // RPC-style protocol |
olympux | 32:db2e8ea06ee1 | 505 | else if (n == 0) { |
olympux | 32:db2e8ea06ee1 | 506 | // then, check query status command and sending protocol if required |
olympux | 32:db2e8ea06ee1 | 507 | if (tcp_receiving_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) { |
olympux | 32:db2e8ea06ee1 | 508 | DBG("Requested to send device status through TCP"); |
olympux | 32:db2e8ea06ee1 | 509 | // sending protocol |
olympux | 32:db2e8ea06ee1 | 510 | update_sending_frame(network_output_buffer); |
olympux | 32:db2e8ea06ee1 | 511 | tcp_sock.send_all(network_output_buffer, SENDING_PROTOCOL_LENGTH); |
olympux | 32:db2e8ea06ee1 | 512 | DBG("Sent"); |
olympux | 32:db2e8ea06ee1 | 513 | } |
olympux | 32:db2e8ea06ee1 | 514 | } // NNIO protocol |
olympux | 18:ca499a2e7da6 | 515 | } |
olympux | 16:84a5bf7285d0 | 516 | } |
olympux | 18:ca499a2e7da6 | 517 | } // if tcp client enabled && auto transmit |
olympux | 15:edeb0aed160d | 518 | #endif |
olympux | 15:edeb0aed160d | 519 | |
olympux | 15:edeb0aed160d | 520 | |
olympux | 30:15e23257e786 | 521 | #ifdef TCP_SERVER // control and monitor from a remote TCP client, both NNIO and RPC-style |
olympux | 30:15e23257e786 | 522 | // no tcp client connected{ |
olympux | 20:71c7950fdd91 | 523 | if (1) { |
olympux | 4:568c97f2a407 | 524 | // wait for client within timeout |
olympux | 4:568c97f2a407 | 525 | ret = tcp_server.accept(tcp_client); |
olympux | 31:2e4b6de6c2f3 | 526 | |
olympux | 4:568c97f2a407 | 527 | // tcp client connected |
olympux | 4:568c97f2a407 | 528 | if (ret > -1) { |
olympux | 18:ca499a2e7da6 | 529 | DBG("Connection from: %s", tcp_client.get_address()); |
olympux | 31:2e4b6de6c2f3 | 530 | |
olympux | 4:568c97f2a407 | 531 | // loop waiting and receiving data within timeout |
olympux | 4:568c97f2a407 | 532 | tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds |
olympux | 31:2e4b6de6c2f3 | 533 | while (tcp_client.is_connected()) { |
olympux | 19:05934ee9ee67 | 534 | n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer)); |
olympux | 4:568c97f2a407 | 535 | if (n <= 0) break; |
olympux | 31:2e4b6de6c2f3 | 536 | |
olympux | 28:00c0c20d03c1 | 537 | // got some data, process it |
olympux | 27:22f289beceb8 | 538 | tcp_receiving_buffer[n] = '\0'; // for debugging purpose |
olympux | 19:05934ee9ee67 | 539 | DBG("TCP server received: %s", tcp_receiving_buffer); |
olympux | 28:00c0c20d03c1 | 540 | n = process_control_command(tcp_receiving_buffer, n); |
olympux | 31:2e4b6de6c2f3 | 541 | // send reply back to client, NNIO protocol always returns 0 |
olympux | 31:2e4b6de6c2f3 | 542 | // RPC-style protocol |
olympux | 28:00c0c20d03c1 | 543 | if (n > 0) { |
olympux | 31:2e4b6de6c2f3 | 544 | network_output_buffer[n] = '\0'; |
olympux | 31:2e4b6de6c2f3 | 545 | tcp_client.send_all(network_output_buffer, strlen(network_output_buffer)); |
olympux | 31:2e4b6de6c2f3 | 546 | } // RPC-style protocol |
olympux | 31:2e4b6de6c2f3 | 547 | else if (n == 0) { |
olympux | 31:2e4b6de6c2f3 | 548 | // then, check query status command and sending protocol if required |
olympux | 31:2e4b6de6c2f3 | 549 | if (tcp_receiving_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) { |
olympux | 31:2e4b6de6c2f3 | 550 | DBG("Requested to send device status through TCP"); |
olympux | 31:2e4b6de6c2f3 | 551 | // sending protocol |
olympux | 31:2e4b6de6c2f3 | 552 | update_sending_frame(network_output_buffer); |
olympux | 31:2e4b6de6c2f3 | 553 | tcp_client.send_all(network_output_buffer, SENDING_PROTOCOL_LENGTH); |
olympux | 31:2e4b6de6c2f3 | 554 | DBG("Sent"); |
olympux | 31:2e4b6de6c2f3 | 555 | } |
olympux | 31:2e4b6de6c2f3 | 556 | } // NNIO protocol |
olympux | 4:568c97f2a407 | 557 | } // end loop if no data received within timeout |
olympux | 4:568c97f2a407 | 558 | } // if client connected |
olympux | 20:71c7950fdd91 | 559 | tcp_client.close(); |
olympux | 18:ca499a2e7da6 | 560 | } // if tcp server enabled && no client connected |
olympux | 3:972ed747474c | 561 | #endif |
olympux | 20:71c7950fdd91 | 562 | |
olympux | 30:15e23257e786 | 563 | #ifdef UDP_SERVER // configuration and control, both NNIO and RPC-style |
olympux | 27:22f289beceb8 | 564 | bool discovery_mode_flag, config_mode_flag; |
olympux | 31:2e4b6de6c2f3 | 565 | |
olympux | 19:05934ee9ee67 | 566 | n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer)); |
olympux | 31:2e4b6de6c2f3 | 567 | |
olympux | 25:48dd18cc147c | 568 | // check to see if it is a query command |
olympux | 25:48dd18cc147c | 569 | // if yes, is it a discovery command or an ip query to enter config mode |
olympux | 27:22f289beceb8 | 570 | discovery_mode_flag = false; |
olympux | 25:48dd18cc147c | 571 | config_mode_flag = false; |
olympux | 26:09e0dd020900 | 572 | if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) { |
olympux | 27:22f289beceb8 | 573 | discovery_mode_flag = true; |
olympux | 25:48dd18cc147c | 574 | DBG("Received discovery command"); |
olympux | 25:48dd18cc147c | 575 | char str[50]; |
olympux | 29:bc052f283ada | 576 | sprintf(str, "%s%s%s", DEVICE_DESCRIPTION, eth.getMACAddress(), eth.getIPAddress()); |
olympux | 25:48dd18cc147c | 577 | udp_server.sendTo(ep_udp_client, str, strlen(str)); |
olympux | 27:22f289beceb8 | 578 | } // NNCFDS |
olympux | 26:09e0dd020900 | 579 | else if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) { |
olympux | 25:48dd18cc147c | 580 | config_mode_flag = true; |
olympux | 27:22f289beceb8 | 581 | DBG("Entered configuration mode..."); |
olympux | 20:71c7950fdd91 | 582 | DBG("!!! RESET when finished"); |
olympux | 27:22f289beceb8 | 583 | } // NNCFIP |
olympux | 31:2e4b6de6c2f3 | 584 | |
olympux | 27:22f289beceb8 | 585 | // if received NNCFIP, enter config mode |
olympux | 25:48dd18cc147c | 586 | if (config_mode_flag) { |
olympux | 31:2e4b6de6c2f3 | 587 | while (n > 0) { |
olympux | 20:71c7950fdd91 | 588 | // got some data, test it |
olympux | 27:22f289beceb8 | 589 | DBG("UDP received (%s) from (%s:%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port()); |
olympux | 26:09e0dd020900 | 590 | process_config_command(udp_receiving_buffer, n); |
olympux | 20:71c7950fdd91 | 591 | // wait to receive new config command |
olympux | 20:71c7950fdd91 | 592 | udp_server.set_blocking(true); |
olympux | 20:71c7950fdd91 | 593 | n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer)); |
olympux | 26:09e0dd020900 | 594 | } // while (n > 0), config loop |
olympux | 25:48dd18cc147c | 595 | } // if (config_mode_flag) |
olympux | 29:bc052f283ada | 596 | // process control packages sent using UDP |
olympux | 29:bc052f283ada | 597 | else if ((n > 0) && (!discovery_mode_flag)) { |
olympux | 28:00c0c20d03c1 | 598 | n = process_control_command(udp_receiving_buffer, n); |
olympux | 28:00c0c20d03c1 | 599 | // send rpc reply back to client, NNIO protocol always returns 0 |
olympux | 31:2e4b6de6c2f3 | 600 | // RPC-style protocol |
olympux | 28:00c0c20d03c1 | 601 | if (n > 0) { |
olympux | 31:2e4b6de6c2f3 | 602 | network_output_buffer[n] = '\0'; |
olympux | 31:2e4b6de6c2f3 | 603 | udp_server.sendTo(ep_udp_client, network_output_buffer, strlen(network_output_buffer)); |
olympux | 31:2e4b6de6c2f3 | 604 | } // RPC-style protocol |
olympux | 31:2e4b6de6c2f3 | 605 | else if (n == 0) { |
olympux | 31:2e4b6de6c2f3 | 606 | // then, check query status command and sending protocol if required |
olympux | 31:2e4b6de6c2f3 | 607 | if (udp_receiving_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) { |
olympux | 31:2e4b6de6c2f3 | 608 | DBG("Requested to send device status through UDP"); |
olympux | 31:2e4b6de6c2f3 | 609 | // sending protocol |
olympux | 31:2e4b6de6c2f3 | 610 | update_sending_frame(network_output_buffer); |
olympux | 31:2e4b6de6c2f3 | 611 | udp_server.sendTo(ep_udp_client, network_output_buffer, SENDING_PROTOCOL_LENGTH); |
olympux | 31:2e4b6de6c2f3 | 612 | DBG("Sent"); |
olympux | 31:2e4b6de6c2f3 | 613 | } |
olympux | 32:db2e8ea06ee1 | 614 | } // NNIO protocol |
olympux | 25:48dd18cc147c | 615 | } |
olympux | 3:972ed747474c | 616 | #endif |
olympux | 4:568c97f2a407 | 617 | } // network processor |
olympux | 11:709f90a3b599 | 618 | } |
olympux | 11:709f90a3b599 | 619 | |
olympux | 26:09e0dd020900 | 620 | |
olympux | 28:00c0c20d03c1 | 621 | /* |
olympux | 28:00c0c20d03c1 | 622 | * Process NNCF commands |
olympux | 28:00c0c20d03c1 | 623 | */ |
olympux | 26:09e0dd020900 | 624 | void process_config_command(char* received_buffer, int len) |
olympux | 26:09e0dd020900 | 625 | { |
olympux | 27:22f289beceb8 | 626 | DBG("Processing configuration command"); |
olympux | 31:2e4b6de6c2f3 | 627 | |
olympux | 26:09e0dd020900 | 628 | // a configuration command always starts with NN |
olympux | 27:22f289beceb8 | 629 | if ((received_buffer[0] == 'N') && (received_buffer[1] == 'N') && |
olympux | 31:2e4b6de6c2f3 | 630 | (received_buffer[2] == 'C') && (received_buffer[3] == 'F')) { |
olympux | 26:09e0dd020900 | 631 | switch (len) { |
olympux | 31:2e4b6de6c2f3 | 632 | // length = 6, a QUERY command (discovery command, TCP port, or UDP port) |
olympux | 31:2e4b6de6c2f3 | 633 | // Format: NNCFDS, NNCFTP, NNCFUP, NNCFTM |
olympux | 30:15e23257e786 | 634 | case QUERY_NETWORK_CONFIG_CMD_LENGTH: { |
olympux | 26:09e0dd020900 | 635 | if (strstr(received_buffer, QUERY_IP_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 636 | udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress())); |
olympux | 27:22f289beceb8 | 637 | } // NNCFIP |
olympux | 26:09e0dd020900 | 638 | else if (strstr(received_buffer, QUERY_SUBNET_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 639 | udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask())); |
olympux | 27:22f289beceb8 | 640 | } // NNCFSN |
olympux | 26:09e0dd020900 | 641 | else if (strstr(received_buffer, QUERY_GATEWAY_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 642 | udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway())); |
olympux | 27:22f289beceb8 | 643 | } // NNCFGW |
olympux | 26:09e0dd020900 | 644 | else if (strstr(received_buffer, QUERY_MAC_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 645 | udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress())); |
olympux | 27:22f289beceb8 | 646 | } // NNCFMC |
olympux | 26:09e0dd020900 | 647 | // ask for TCP server port |
olympux | 26:09e0dd020900 | 648 | else if (strstr(received_buffer, QUERY_TCP_PORT_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 649 | char port[5]; |
olympux | 26:09e0dd020900 | 650 | sprintf(port, "%5d", tcp_server_local_port); |
olympux | 26:09e0dd020900 | 651 | udp_server.sendTo(ep_udp_client, port, strlen(port)); |
olympux | 27:22f289beceb8 | 652 | } // NNCFTP |
olympux | 26:09e0dd020900 | 653 | // ask for UDP server port |
olympux | 26:09e0dd020900 | 654 | else if (strstr(received_buffer, QUERY_UDP_PORT_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 655 | char port[5]; |
olympux | 26:09e0dd020900 | 656 | sprintf(port, "%5d", udp_server_local_port); |
olympux | 26:09e0dd020900 | 657 | udp_server.sendTo(ep_udp_client, port, strlen(port)); |
olympux | 27:22f289beceb8 | 658 | } // NNCFUP |
olympux | 26:09e0dd020900 | 659 | else if (strstr(received_buffer, QUERY_UPDATE_TIME_CMD) != NULL) { |
olympux | 26:09e0dd020900 | 660 | #ifdef NTP |
olympux | 26:09e0dd020900 | 661 | char str_time[50]; |
olympux | 26:09e0dd020900 | 662 | |
olympux | 26:09e0dd020900 | 663 | DBG("Trying to update time..."); |
olympux | 26:09e0dd020900 | 664 | if (ntp.setTime("0.pool.ntp.org") == 0) { |
olympux | 26:09e0dd020900 | 665 | DBG("Set time successfully"); |
olympux | 26:09e0dd020900 | 666 | time_t ctTime; |
olympux | 26:09e0dd020900 | 667 | ctTime = time(NULL); |
olympux | 26:09e0dd020900 | 668 | |
olympux | 26:09e0dd020900 | 669 | DBG("Time is set to (UTC): %s", ctime(&ctTime)); |
olympux | 26:09e0dd020900 | 670 | sprintf(str_time, "%s", ctime(&ctTime)); |
olympux | 26:09e0dd020900 | 671 | udp_server.sendTo(ep_udp_client, str_time, strlen(str_time)); |
olympux | 26:09e0dd020900 | 672 | } else { |
olympux | 26:09e0dd020900 | 673 | WARN("Error"); |
olympux | 26:09e0dd020900 | 674 | sprintf(str_time, "ERR"); |
olympux | 26:09e0dd020900 | 675 | udp_server.sendTo(ep_udp_client, str_time, strlen(str_time)); |
olympux | 26:09e0dd020900 | 676 | } |
olympux | 37:94b847fea94e | 677 | #else |
olympux | 26:09e0dd020900 | 678 | WARN("NTP disabled"); |
olympux | 26:09e0dd020900 | 679 | sprintf(str_time, "DIS"); |
olympux | 26:09e0dd020900 | 680 | udp_server.sendTo(ep_udp_client, str_time, strlen(str_time)); |
olympux | 26:09e0dd020900 | 681 | #endif |
olympux | 27:22f289beceb8 | 682 | } // NNCFTM |
olympux | 26:09e0dd020900 | 683 | break; |
olympux | 30:15e23257e786 | 684 | } |
olympux | 30:15e23257e786 | 685 | // length = 19, SET NETWORK CONFIGURATION |
olympux | 30:15e23257e786 | 686 | // Format: 4E 4E 43 46 C0 A8 00 78 FF FF FF 00 C0 A8 00 01 00 00 01 |
olympux | 30:15e23257e786 | 687 | // (NNCF; IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1) |
olympux | 26:09e0dd020900 | 688 | case SET_NETWORK_CONFIG_CMD_LENGTH: { |
olympux | 26:09e0dd020900 | 689 | // check device id |
olympux | 27:22f289beceb8 | 690 | char* id = strstr(received_buffer, DEVICE_CONFIG_CODE); |
olympux | 26:09e0dd020900 | 691 | if (id == NULL) |
olympux | 26:09e0dd020900 | 692 | break; |
olympux | 26:09e0dd020900 | 693 | else if ((id - received_buffer) > 0) |
olympux | 26:09e0dd020900 | 694 | break; |
olympux | 26:09e0dd020900 | 695 | |
olympux | 26:09e0dd020900 | 696 | DBG("Received user configuration"); |
olympux | 27:22f289beceb8 | 697 | write_eeprom_network(&received_buffer[strlen(DEVICE_CONFIG_CODE)]); // parameters from 5th char, 15-bytes |
olympux | 33:c906ccc220ba | 698 | NVIC_SystemReset(); |
olympux | 26:09e0dd020900 | 699 | break; |
olympux | 26:09e0dd020900 | 700 | } |
olympux | 26:09e0dd020900 | 701 | // length = 12, SET TCP SERVER CONFIGURATION |
olympux | 26:09e0dd020900 | 702 | // auto update & its time period, TCP server configuration (IP & port) |
olympux | 27:22f289beceb8 | 703 | // Format: 4E 4E 43 46 'Y' 01 C0 A8 00 09 E0 2E (LSB MSB) |
olympux | 27:22f289beceb8 | 704 | // NNCF Auto 1s 192.168.0.9 12000 |
olympux | 26:09e0dd020900 | 705 | case UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH: { |
olympux | 27:22f289beceb8 | 706 | char* id = strstr(received_buffer, DEVICE_CONFIG_CODE); |
olympux | 26:09e0dd020900 | 707 | if (id == NULL) |
olympux | 26:09e0dd020900 | 708 | break; |
olympux | 26:09e0dd020900 | 709 | else if ((id - received_buffer) > 0) |
olympux | 26:09e0dd020900 | 710 | break; |
olympux | 26:09e0dd020900 | 711 | |
olympux | 26:09e0dd020900 | 712 | DBG("Received TCP server configuration"); |
olympux | 27:22f289beceb8 | 713 | write_eeprom_tcpserver(&received_buffer[strlen(DEVICE_CONFIG_CODE)]); // parameters from 5th char |
olympux | 33:c906ccc220ba | 714 | NVIC_SystemReset(); |
olympux | 26:09e0dd020900 | 715 | break; |
olympux | 26:09e0dd020900 | 716 | } |
olympux | 26:09e0dd020900 | 717 | default: |
olympux | 26:09e0dd020900 | 718 | break; |
olympux | 26:09e0dd020900 | 719 | } // switch (n), check configuration command length |
olympux | 27:22f289beceb8 | 720 | } // if starts with NNCF, a config command |
olympux | 30:15e23257e786 | 721 | else { // if not a configuration command |
olympux | 26:09e0dd020900 | 722 | } |
olympux | 26:09e0dd020900 | 723 | } |
olympux | 26:09e0dd020900 | 724 | |
olympux | 12:7c152c0ca4d8 | 725 | /* |
olympux | 30:15e23257e786 | 726 | * Procedure to process receiving protocol, which includes command to control outputs. |
olympux | 30:15e23257e786 | 727 | * Support both NNIO and RPC-style commands. |
olympux | 30:15e23257e786 | 728 | * RPC always starts with '/'. |
olympux | 30:15e23257e786 | 729 | * Return: |
olympux | 30:15e23257e786 | 730 | * 0 if NNIO protocol; |
olympux | 30:15e23257e786 | 731 | * length of rpc output buffer if rpc; |
olympux | 30:15e23257e786 | 732 | * -1 if rpc failed |
olympux | 28:00c0c20d03c1 | 733 | */ |
olympux | 28:00c0c20d03c1 | 734 | int process_control_command(char* received_buffer, int len) |
olympux | 26:09e0dd020900 | 735 | { |
olympux | 26:09e0dd020900 | 736 | char* received_frame; |
olympux | 30:15e23257e786 | 737 | bool rpc_style; |
olympux | 26:09e0dd020900 | 738 | int pos; |
olympux | 31:2e4b6de6c2f3 | 739 | char inbuf[NET_BUF_LEN]; |
olympux | 31:2e4b6de6c2f3 | 740 | |
olympux | 27:22f289beceb8 | 741 | DBG("Processing control command"); |
olympux | 31:2e4b6de6c2f3 | 742 | |
olympux | 30:15e23257e786 | 743 | /* |
olympux | 30:15e23257e786 | 744 | * This section is for RPC-style command |
olympux | 30:15e23257e786 | 745 | */ |
olympux | 30:15e23257e786 | 746 | // check if it is a RPC-style command |
olympux | 30:15e23257e786 | 747 | rpc_style = false; |
olympux | 27:22f289beceb8 | 748 | strncpy(inbuf, received_buffer, len); |
olympux | 27:22f289beceb8 | 749 | inbuf[len] = '\r'; // use inbuf for RPC protocol |
olympux | 27:22f289beceb8 | 750 | inbuf[len+1] = '\n'; |
olympux | 27:22f289beceb8 | 751 | inbuf[len+2] = '\0'; // add CR-LF |
olympux | 27:22f289beceb8 | 752 | if ((len > 0) && (inbuf[0] == '/')) { |
olympux | 34:32299b819067 | 753 | char obj_name[16]; |
olympux | 34:32299b819067 | 754 | bool ok; |
olympux | 31:2e4b6de6c2f3 | 755 | |
olympux | 30:15e23257e786 | 756 | rpc_style = true; |
olympux | 29:bc052f283ada | 757 | // find RPC object name |
olympux | 29:bc052f283ada | 758 | for (int i = 1; i < strlen(inbuf); i++) { |
olympux | 29:bc052f283ada | 759 | if (inbuf[i] != '/') { |
olympux | 29:bc052f283ada | 760 | obj_name[i-1] = inbuf[i]; |
olympux | 31:2e4b6de6c2f3 | 761 | } else { |
olympux | 29:bc052f283ada | 762 | obj_name[i-1] = '\0'; |
olympux | 29:bc052f283ada | 763 | break; |
olympux | 29:bc052f283ada | 764 | } |
olympux | 29:bc052f283ada | 765 | } |
olympux | 28:00c0c20d03c1 | 766 | DBG("Rpc command = %s", inbuf); |
olympux | 29:bc052f283ada | 767 | /* |
olympux | 29:bc052f283ada | 768 | * execute RPC command, return reply length and reply in rpc_outbuf |
olympux | 29:bc052f283ada | 769 | */ |
olympux | 34:32299b819067 | 770 | ok = RPC::call(inbuf, network_output_buffer); |
olympux | 34:32299b819067 | 771 | if (ok) { |
olympux | 29:bc052f283ada | 772 | // re-arrange output buffer as following: object_name:output_value |
olympux | 31:2e4b6de6c2f3 | 773 | strcpy(inbuf, network_output_buffer); // use inbuf as temp |
olympux | 31:2e4b6de6c2f3 | 774 | strcpy(network_output_buffer, obj_name); // rpc object name |
olympux | 31:2e4b6de6c2f3 | 775 | strcat(network_output_buffer, ":"); |
olympux | 31:2e4b6de6c2f3 | 776 | strcat(network_output_buffer, inbuf); // concat rpc reply |
olympux | 31:2e4b6de6c2f3 | 777 | strcat(network_output_buffer, "\r\n"); // CR-LF |
olympux | 31:2e4b6de6c2f3 | 778 | int j = strlen(network_output_buffer); |
olympux | 31:2e4b6de6c2f3 | 779 | DBG("Reply of rpc command on \"%s\" (%d bytes): %s", obj_name, j, network_output_buffer); |
olympux | 29:bc052f283ada | 780 | return j; // return length of rpc_outbuf |
olympux | 31:2e4b6de6c2f3 | 781 | } else { |
olympux | 27:22f289beceb8 | 782 | ERR("Failed: %s", inbuf); |
olympux | 28:00c0c20d03c1 | 783 | return -1; |
olympux | 27:22f289beceb8 | 784 | } |
olympux | 27:22f289beceb8 | 785 | } |
olympux | 31:2e4b6de6c2f3 | 786 | |
olympux | 28:00c0c20d03c1 | 787 | /* |
olympux | 28:00c0c20d03c1 | 788 | * This section below is for NNIO protocol |
olympux | 28:00c0c20d03c1 | 789 | */ |
olympux | 30:15e23257e786 | 790 | while ((!rpc_style) && (len >= RECEIVING_PROTOCOL_LENGTH)) { |
olympux | 26:09e0dd020900 | 791 | // find device ID |
olympux | 26:09e0dd020900 | 792 | DBG("Checking device ID..."); |
olympux | 27:22f289beceb8 | 793 | char* id = strstr(received_buffer, DEVICE_CONTROL_CODE); |
olympux | 26:09e0dd020900 | 794 | if (id == NULL) { |
olympux | 26:09e0dd020900 | 795 | DBG("No device ID found"); |
olympux | 26:09e0dd020900 | 796 | break; |
olympux | 26:09e0dd020900 | 797 | } |
olympux | 26:09e0dd020900 | 798 | pos = id - received_buffer; |
olympux | 26:09e0dd020900 | 799 | DBG("Found a frame at %d", pos); |
olympux | 31:2e4b6de6c2f3 | 800 | |
olympux | 26:09e0dd020900 | 801 | // extract this frame |
olympux | 26:09e0dd020900 | 802 | received_frame = &received_buffer[pos]; |
olympux | 26:09e0dd020900 | 803 | // calculate the rest |
olympux | 26:09e0dd020900 | 804 | received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH]; |
olympux | 26:09e0dd020900 | 805 | len -= RECEIVING_PROTOCOL_LENGTH; |
olympux | 31:2e4b6de6c2f3 | 806 | |
olympux | 26:09e0dd020900 | 807 | // process this received frame |
olympux | 26:09e0dd020900 | 808 | // firstly, update outputs if required |
olympux | 26:09e0dd020900 | 809 | // digital outputs |
olympux | 26:09e0dd020900 | 810 | if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) { |
olympux | 26:09e0dd020900 | 811 | DBG("Update digital outputs"); |
olympux | 26:09e0dd020900 | 812 | char str_dout[9]; |
olympux | 26:09e0dd020900 | 813 | memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8); |
olympux | 26:09e0dd020900 | 814 | str_dout[8] = '\0'; |
olympux | 26:09e0dd020900 | 815 | update_digital_outputs(str_dout); |
olympux | 26:09e0dd020900 | 816 | } |
olympux | 26:09e0dd020900 | 817 | // analog output 0 |
olympux | 26:09e0dd020900 | 818 | if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) { |
olympux | 26:09e0dd020900 | 819 | DBG("Update analog output 0"); |
olympux | 26:09e0dd020900 | 820 | //TODO Update analog output |
olympux | 26:09e0dd020900 | 821 | } |
olympux | 26:09e0dd020900 | 822 | // analog output 1 |
olympux | 26:09e0dd020900 | 823 | if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) { |
olympux | 26:09e0dd020900 | 824 | DBG("Update analog output 1"); |
olympux | 26:09e0dd020900 | 825 | //TODO Update analog output |
olympux | 26:09e0dd020900 | 826 | } |
olympux | 26:09e0dd020900 | 827 | // UART |
olympux | 26:09e0dd020900 | 828 | if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) { |
olympux | 26:09e0dd020900 | 829 | DBG("UART data: "); |
olympux | 26:09e0dd020900 | 830 | char str_uart[33]; |
olympux | 26:09e0dd020900 | 831 | memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32); |
olympux | 26:09e0dd020900 | 832 | str_uart[32] = '\0'; |
olympux | 26:09e0dd020900 | 833 | uart.printf("%s\r\n", str_uart); |
olympux | 26:09e0dd020900 | 834 | } |
olympux | 26:09e0dd020900 | 835 | } |
olympux | 31:2e4b6de6c2f3 | 836 | |
olympux | 27:22f289beceb8 | 837 | DBG("Successfully processed."); |
olympux | 28:00c0c20d03c1 | 838 | return 0; |
olympux | 26:09e0dd020900 | 839 | } |
olympux | 26:09e0dd020900 | 840 | |
olympux | 26:09e0dd020900 | 841 | |
olympux | 26:09e0dd020900 | 842 | /* |
olympux | 26:09e0dd020900 | 843 | * W5500 Ethernet init |
olympux | 26:09e0dd020900 | 844 | */ |
olympux | 31:2e4b6de6c2f3 | 845 | int ethernet_init(void) |
olympux | 31:2e4b6de6c2f3 | 846 | { |
olympux | 26:09e0dd020900 | 847 | int dhcp_ret, ret; |
olympux | 31:2e4b6de6c2f3 | 848 | |
olympux | 27:22f289beceb8 | 849 | DBG("Initialising ethernet..."); |
olympux | 31:2e4b6de6c2f3 | 850 | |
olympux | 26:09e0dd020900 | 851 | // if not configured, try dhcp |
olympux | 26:09e0dd020900 | 852 | dhcp_ret = -1; |
olympux | 26:09e0dd020900 | 853 | if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) { |
olympux | 27:22f289beceb8 | 854 | DBG("Connecting to DHCP server..."); |
olympux | 26:09e0dd020900 | 855 | dhcp_ret = eth.init(u8mac); |
olympux | 26:09e0dd020900 | 856 | if (dhcp_ret == 0) |
olympux | 26:09e0dd020900 | 857 | dhcp_ret = eth.connect(); |
olympux | 26:09e0dd020900 | 858 | } |
olympux | 31:2e4b6de6c2f3 | 859 | |
olympux | 26:09e0dd020900 | 860 | if (dhcp_ret != 0) { |
olympux | 26:09e0dd020900 | 861 | DBG("No DHCP, load static IP configuration"); |
olympux | 26:09e0dd020900 | 862 | ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static |
olympux | 26:09e0dd020900 | 863 | } else { |
olympux | 26:09e0dd020900 | 864 | snprintf(str_ip_addr, 16, "%s", eth.getIPAddress()); |
olympux | 26:09e0dd020900 | 865 | snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask()); |
olympux | 26:09e0dd020900 | 866 | snprintf(str_ip_gateway, 16, "%s", eth.getGateway()); |
olympux | 26:09e0dd020900 | 867 | ret = 0; |
olympux | 26:09e0dd020900 | 868 | } |
olympux | 26:09e0dd020900 | 869 | |
olympux | 26:09e0dd020900 | 870 | if (ret == 0) { |
olympux | 26:09e0dd020900 | 871 | DBG("Initialized, MAC: %s", eth.getMACAddress()); |
olympux | 26:09e0dd020900 | 872 | } else { |
olympux | 26:09e0dd020900 | 873 | ERR("Error eth.init() - ret = %d", ret); |
olympux | 26:09e0dd020900 | 874 | return -1; |
olympux | 26:09e0dd020900 | 875 | } |
olympux | 26:09e0dd020900 | 876 | |
olympux | 26:09e0dd020900 | 877 | ret = eth.connect(); |
olympux | 26:09e0dd020900 | 878 | if (!ret) { |
olympux | 26:09e0dd020900 | 879 | DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway()); |
olympux | 26:09e0dd020900 | 880 | } else { |
olympux | 26:09e0dd020900 | 881 | ERR("Error eth.connect() - ret = %d", ret); |
olympux | 26:09e0dd020900 | 882 | return -1; |
olympux | 26:09e0dd020900 | 883 | } |
olympux | 31:2e4b6de6c2f3 | 884 | |
olympux | 26:09e0dd020900 | 885 | return 0; |
olympux | 26:09e0dd020900 | 886 | } |
olympux | 26:09e0dd020900 | 887 | |
olympux | 26:09e0dd020900 | 888 | |
olympux | 26:09e0dd020900 | 889 | /* |
olympux | 26:09e0dd020900 | 890 | * Update digital outputs according to receiving protocol |
olympux | 12:7c152c0ca4d8 | 891 | */ |
olympux | 31:2e4b6de6c2f3 | 892 | void update_digital_outputs(char* buf) |
olympux | 31:2e4b6de6c2f3 | 893 | { |
olympux | 18:ca499a2e7da6 | 894 | DBG("Digital outputs: %s", buf); |
olympux | 31:2e4b6de6c2f3 | 895 | |
olympux | 12:7c152c0ca4d8 | 896 | dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 897 | dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 898 | dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 899 | dout3 = (buf[3] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 900 | dout4 = (buf[4] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 901 | dout5 = (buf[5] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 902 | dout6 = (buf[6] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 903 | dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0; |
olympux | 12:7c152c0ca4d8 | 904 | } |
olympux | 12:7c152c0ca4d8 | 905 | |
olympux | 26:09e0dd020900 | 906 | /* |
olympux | 26:09e0dd020900 | 907 | * Prepare a frame for sending protocol, which includes status of I/Os |
olympux | 26:09e0dd020900 | 908 | */ |
olympux | 31:2e4b6de6c2f3 | 909 | void update_sending_frame(char* buf) |
olympux | 31:2e4b6de6c2f3 | 910 | { |
olympux | 27:22f289beceb8 | 911 | memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_CONTROL_CODE, 4); // device id |
olympux | 12:7c152c0ca4d8 | 912 | memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6); |
olympux | 12:7c152c0ca4d8 | 913 | memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4); |
olympux | 31:2e4b6de6c2f3 | 914 | |
olympux | 12:7c152c0ca4d8 | 915 | buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 916 | buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 917 | buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 918 | buf[SENDING_PROTOCOL_DI_POS+3] = (din3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 919 | buf[SENDING_PROTOCOL_DI_POS+4] = (din4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 920 | buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 921 | buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 922 | buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 31:2e4b6de6c2f3 | 923 | |
olympux | 12:7c152c0ca4d8 | 924 | buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 925 | buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 926 | buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 927 | buf[SENDING_PROTOCOL_DO_POS+3] = (dout3 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 928 | buf[SENDING_PROTOCOL_DO_POS+4] = (dout4 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 929 | buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 930 | buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 12:7c152c0ca4d8 | 931 | buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW; |
olympux | 31:2e4b6de6c2f3 | 932 | |
olympux | 15:edeb0aed160d | 933 | uint16_t val = ain0.read_u16(); // 16-bits normalised |
olympux | 15:edeb0aed160d | 934 | memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB |
olympux | 15:edeb0aed160d | 935 | val = ain1.read_u16(); // 16-bits normalised |
olympux | 15:edeb0aed160d | 936 | memcpy(&buf[SENDING_PROTOCOL_AI1_POS], &val, 2); // LSB MSB |
olympux | 23:47ee805435b1 | 937 | val = 0x1234; |
olympux | 15:edeb0aed160d | 938 | memcpy(&buf[SENDING_PROTOCOL_AO0_POS], &val, 2); // LSB MSB |
olympux | 23:47ee805435b1 | 939 | val = 0x5678; |
olympux | 15:edeb0aed160d | 940 | memcpy(&buf[SENDING_PROTOCOL_AO1_POS], &val, 2); // LSB MSB |
olympux | 12:7c152c0ca4d8 | 941 | buf[SENDING_PROTOCOL_CR_POS] = 0x0D; |
olympux | 12:7c152c0ca4d8 | 942 | buf[SENDING_PROTOCOL_CR_POS+1] = '\0'; |
olympux | 4:568c97f2a407 | 943 | } |