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 Sep 21 19:35:32 2014 +0000
Revision:
6:d054e394fba3
Parent:
4:568c97f2a407
Child:
7:d45bd480e90f
Tested writing and reading eeprom. Added set network configuration command (use udp broadcast address).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
olympux 0:c2eac797face 1 /*
olympux 0:c2eac797face 2 *
olympux 2:18f10e7209f4 3 * Alarm and Monitoring application
olympux 0:c2eac797face 4
olympux 0:c2eac797face 5 */
olympux 0:c2eac797face 6 #include "mbed.h"
olympux 6:d054e394fba3 7 //#include "eeprom.h"
olympux 0:c2eac797face 8 #include "EthernetInterface.h"
olympux 0:c2eac797face 9 #include "rtos.h"
olympux 0:c2eac797face 10
olympux 0:c2eac797face 11
olympux 2:18f10e7209f4 12 /*
olympux 2:18f10e7209f4 13 * Hardware defines
olympux 0:c2eac797face 14 */
olympux 2:18f10e7209f4 15 #define ST_NUCLEO // hardware pin mapping
olympux 0:c2eac797face 16
olympux 0:c2eac797face 17 #ifdef ST_NUCLEO
olympux 0:c2eac797face 18 // ST Nucleo
olympux 0:c2eac797face 19 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
olympux 0:c2eac797face 20 EthernetInterface eth(&spi, PC_8, PC_9); // spi, cs, reset
olympux 0:c2eac797face 21 #endif
olympux 0:c2eac797face 22
olympux 2:18f10e7209f4 23 Serial uart(USBTX,USBRX);
olympux 2:18f10e7209f4 24
olympux 6:d054e394fba3 25 // Variables' number
olympux 6:d054e394fba3 26 #define NumbOfVar ((uint8_t)0x0E) // REMEMBER: update this variable in eeprom.h too
olympux 6:d054e394fba3 27 // Virtual address defined by the user: 0xFFFF value is prohibited
olympux 6:d054e394fba3 28 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
olympux 6:d054e394fba3 29 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
olympux 6:d054e394fba3 30 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
olympux 6:d054e394fba3 31 0x4212, // TCP server port, not used
olympux 6:d054e394fba3 32 0x5212 // UDP server port, not used
olympux 6:d054e394fba3 33 };
olympux 6:d054e394fba3 34 extern "C" uint16_t EE_Init(void);
olympux 6:d054e394fba3 35 extern "C" uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
olympux 6:d054e394fba3 36 extern "C" uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
olympux 4:568c97f2a407 37
olympux 0:c2eac797face 38
olympux 2:18f10e7209f4 39 /*
olympux 2:18f10e7209f4 40 * Network configuration
olympux 2:18f10e7209f4 41 */
olympux 4:568c97f2a407 42 #define TCP_SERVER
olympux 4:568c97f2a407 43 //#define TCP_CLIENT
olympux 4:568c97f2a407 44 #define UDP_SERVER
olympux 4:568c97f2a407 45 //#define UDP_CLIENT
olympux 4:568c97f2a407 46 //#define NTP
olympux 4:568c97f2a407 47
olympux 4:568c97f2a407 48 #define TCP_SERVER_WAIT_CLIENT_TIMEOUT 200
olympux 4:568c97f2a407 49 #define TCP_SERVER_RECEIVE_TIMEOUT 3000
olympux 4:568c97f2a407 50 #define UDP_SERVER_RECEIVE_TIMEOUT 200
olympux 4:568c97f2a407 51
olympux 0:c2eac797face 52 // for static IP setting
olympux 4:568c97f2a407 53 char * IP_Addr = "192.168.0.120";
olympux 6:d054e394fba3 54 char * IP_Subnet = "255.255.255.0";
olympux 6:d054e394fba3 55 char * IP_Gateway = "192.168.0.1";
olympux 6:d054e394fba3 56 char ip_addr[16], ip_subnet[16], ip_gateway[16]; // loaded from eeprom
olympux 6:d054e394fba3 57
olympux 6:d054e394fba3 58 uint16_t tcp_server_port = 10000; // fixed
olympux 6:d054e394fba3 59 uint16_t udp_server_port = 11000; // fixed
olympux 0:c2eac797face 60
olympux 3:972ed747474c 61 char buffer[256]; // socket buffer
olympux 3:972ed747474c 62
olympux 0:c2eac797face 63
olympux 2:18f10e7209f4 64
olympux 2:18f10e7209f4 65 /*
olympux 2:18f10e7209f4 66 * RTOS
olympux 2:18f10e7209f4 67 */
olympux 2:18f10e7209f4 68 struct message_t {
olympux 2:18f10e7209f4 69 int len;
olympux 2:18f10e7209f4 70 char *msg;
olympux 2:18f10e7209f4 71 };
olympux 3:972ed747474c 72 Queue<message_t, 16> uart_queue;
olympux 2:18f10e7209f4 73
olympux 3:972ed747474c 74 Mutex uart_mutex;
olympux 2:18f10e7209f4 75
olympux 2:18f10e7209f4 76
olympux 2:18f10e7209f4 77 /*
olympux 2:18f10e7209f4 78 * Threads
olympux 2:18f10e7209f4 79 */
olympux 0:c2eac797face 80 void uart_thread(void const *args) {
olympux 2:18f10e7209f4 81 message_t *p_message;
olympux 0:c2eac797face 82
olympux 0:c2eac797face 83 while (true) {
olympux 3:972ed747474c 84 osEvent evt = uart_queue.get();
olympux 2:18f10e7209f4 85 if (evt.status == osEventMessage) {
olympux 2:18f10e7209f4 86 p_message = (message_t*)evt.value.p;
olympux 3:972ed747474c 87 uart_mutex.lock();
olympux 3:972ed747474c 88 //uart.printf("len=%d\n", p_message->len);
olympux 3:972ed747474c 89 uart.printf("%s\n", p_message->msg);
olympux 3:972ed747474c 90 uart_mutex.unlock();
olympux 2:18f10e7209f4 91 }
olympux 0:c2eac797face 92 }
olympux 0:c2eac797face 93 }
olympux 0:c2eac797face 94
olympux 0:c2eac797face 95
olympux 6:d054e394fba3 96 /*
olympux 6:d054e394fba3 97 * Ethernet init
olympux 6:d054e394fba3 98 */
olympux 4:568c97f2a407 99 int ethernet_init(void) {
olympux 3:972ed747474c 100 uint8_t mac[6];
olympux 3:972ed747474c 101
olympux 0:c2eac797face 102 mbed_mac_address((char *)mac); // using the MAC address in LPC11U24 or LPC1178
olympux 0:c2eac797face 103 mac[0] = 0x00; mac[1] = 0x08; mac[2] = 0xDC; mac[3] = 0x00; mac[4] = 0x00; mac[5] = 0x00;
olympux 0:c2eac797face 104
olympux 4:568c97f2a407 105
olympux 3:972ed747474c 106 printf("Start\n");
olympux 6:d054e394fba3 107 int ret = eth.init(mac, IP_Addr, IP_Subnet, IP_Gateway); // static
olympux 0:c2eac797face 108
olympux 0:c2eac797face 109 if (!ret) {
olympux 2:18f10e7209f4 110 uart.printf("Initialized, MAC: %s\n", eth.getMACAddress());
olympux 0:c2eac797face 111 } else {
olympux 2:18f10e7209f4 112 uart.printf("Error eth.init() - ret = %d\n", ret);
olympux 0:c2eac797face 113 return -1;
olympux 0:c2eac797face 114 }
olympux 0:c2eac797face 115
olympux 0:c2eac797face 116 ret = eth.connect();
olympux 0:c2eac797face 117 if (!ret) {
olympux 3:972ed747474c 118 uart.printf("IP: %s, MASK: %s, GW: %s\n", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 0:c2eac797face 119 } else {
olympux 2:18f10e7209f4 120 uart.printf("Error eth.connect() - ret = %d\n", ret);
olympux 0:c2eac797face 121 return -1;
olympux 0:c2eac797face 122 }
olympux 3:972ed747474c 123
olympux 4:568c97f2a407 124 return 0;
olympux 4:568c97f2a407 125 }
olympux 4:568c97f2a407 126
olympux 4:568c97f2a407 127
olympux 6:d054e394fba3 128 /*
olympux 6:d054e394fba3 129 * EEPROM functions
olympux 6:d054e394fba3 130 */
olympux 6:d054e394fba3 131 void write_eeprom(char *buffer) {
olympux 6:d054e394fba3 132 // Unlock the Flash Program Erase controller */
olympux 6:d054e394fba3 133 FLASH_Unlock();
olympux 6:d054e394fba3 134 // EEPROM Init
olympux 6:d054e394fba3 135 EE_Init();
olympux 6:d054e394fba3 136 // IP address
olympux 6:d054e394fba3 137 EE_WriteVariable(VirtAddVarTab[0], *buffer++);
olympux 6:d054e394fba3 138 EE_WriteVariable(VirtAddVarTab[1], *buffer++);
olympux 6:d054e394fba3 139 EE_WriteVariable(VirtAddVarTab[2], *buffer++);
olympux 6:d054e394fba3 140 EE_WriteVariable(VirtAddVarTab[3], *buffer++);
olympux 6:d054e394fba3 141 // IP subnet
olympux 6:d054e394fba3 142 EE_WriteVariable(VirtAddVarTab[4], *buffer++);
olympux 6:d054e394fba3 143 EE_WriteVariable(VirtAddVarTab[5], *buffer++);
olympux 6:d054e394fba3 144 EE_WriteVariable(VirtAddVarTab[6], *buffer++);
olympux 6:d054e394fba3 145 EE_WriteVariable(VirtAddVarTab[7], *buffer++);
olympux 6:d054e394fba3 146 // IP gateway
olympux 6:d054e394fba3 147 EE_WriteVariable(VirtAddVarTab[8], *buffer++);
olympux 6:d054e394fba3 148 EE_WriteVariable(VirtAddVarTab[9], *buffer++);
olympux 6:d054e394fba3 149 EE_WriteVariable(VirtAddVarTab[10], *buffer++);
olympux 6:d054e394fba3 150 EE_WriteVariable(VirtAddVarTab[11], *buffer++);
olympux 6:d054e394fba3 151 //// TCP server port
olympux 6:d054e394fba3 152 //EE_WriteVariable(VirtAddVarTab[12], *buffer++);
olympux 6:d054e394fba3 153 //// UDP server port
olympux 6:d054e394fba3 154 //EE_WriteVariable(VirtAddVarTab[13], *buffer++);
olympux 6:d054e394fba3 155 FLASH_Lock();
olympux 6:d054e394fba3 156 }
olympux 6:d054e394fba3 157
olympux 6:d054e394fba3 158
olympux 6:d054e394fba3 159 void load_eeprom(void) {
olympux 6:d054e394fba3 160 // Load IP adddress
olympux 6:d054e394fba3 161 uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4];
olympux 6:d054e394fba3 162 //FLASH_Unlock();
olympux 6:d054e394fba3 163 EE_Init();
olympux 6:d054e394fba3 164 // IP address
olympux 6:d054e394fba3 165 EE_ReadVariable(VirtAddVarTab[0], &u16ip_addr[0]);
olympux 6:d054e394fba3 166 EE_ReadVariable(VirtAddVarTab[1], &u16ip_addr[1]);
olympux 6:d054e394fba3 167 EE_ReadVariable(VirtAddVarTab[2], &u16ip_addr[2]);
olympux 6:d054e394fba3 168 EE_ReadVariable(VirtAddVarTab[3], &u16ip_addr[3]);
olympux 6:d054e394fba3 169 // IP subnet
olympux 6:d054e394fba3 170 EE_ReadVariable(VirtAddVarTab[4], &u16ip_subnet[0]);
olympux 6:d054e394fba3 171 EE_ReadVariable(VirtAddVarTab[5], &u16ip_subnet[1]);
olympux 6:d054e394fba3 172 EE_ReadVariable(VirtAddVarTab[6], &u16ip_subnet[2]);
olympux 6:d054e394fba3 173 EE_ReadVariable(VirtAddVarTab[7], &u16ip_subnet[3]);
olympux 6:d054e394fba3 174 // IP gateway
olympux 6:d054e394fba3 175 EE_ReadVariable(VirtAddVarTab[8], &u16ip_gateway[0]);
olympux 6:d054e394fba3 176 EE_ReadVariable(VirtAddVarTab[9], &u16ip_gateway[1]);
olympux 6:d054e394fba3 177 EE_ReadVariable(VirtAddVarTab[10], &u16ip_gateway[2]);
olympux 6:d054e394fba3 178 EE_ReadVariable(VirtAddVarTab[11], &u16ip_gateway[3]);
olympux 6:d054e394fba3 179 //// TCP server port
olympux 6:d054e394fba3 180 //EE_ReadVariable(VirtAddVarTab[12], &tcp_server_port);
olympux 6:d054e394fba3 181 //// UDP server port
olympux 6:d054e394fba3 182 //EE_ReadVariable(VirtAddVarTab[13], &udp_server_port);
olympux 6:d054e394fba3 183 //FLASH_Lock();
olympux 6:d054e394fba3 184 sprintf(ip_addr, "%d.%d.%d.%d", (uint8_t)u16ip_addr[0], (uint8_t)u16ip_addr[1], (uint8_t)u16ip_addr[2], (uint8_t)u16ip_addr[3]);
olympux 6:d054e394fba3 185 sprintf(ip_subnet, "%d.%d.%d.%d", (uint8_t)u16ip_subnet[0], (uint8_t)u16ip_subnet[1], (uint8_t)u16ip_subnet[2], (uint8_t)u16ip_subnet[3]);
olympux 6:d054e394fba3 186 sprintf(ip_gateway, "%d.%d.%d.%d", (uint8_t)u16ip_gateway[0], (uint8_t)u16ip_gateway[1], (uint8_t)u16ip_gateway[2], (uint8_t)u16ip_gateway[3]);
olympux 6:d054e394fba3 187 printf("IP: %s\n", ip_addr);
olympux 6:d054e394fba3 188 printf("MASK: %s\n", ip_subnet);
olympux 6:d054e394fba3 189 printf("GW: %s\n", ip_gateway);
olympux 6:d054e394fba3 190 printf("TCP: %d\n", tcp_server_port);
olympux 6:d054e394fba3 191 printf("UDP: %d\n", udp_server_port);
olympux 6:d054e394fba3 192 }
olympux 6:d054e394fba3 193
olympux 6:d054e394fba3 194
olympux 4:568c97f2a407 195
olympux 4:568c97f2a407 196 int main()
olympux 4:568c97f2a407 197 {
olympux 4:568c97f2a407 198 message_t message;
olympux 6:d054e394fba3 199 int ret;
olympux 4:568c97f2a407 200
olympux 4:568c97f2a407 201 /*
olympux 4:568c97f2a407 202 * configure
olympux 4:568c97f2a407 203 */
olympux 4:568c97f2a407 204 uart.baud(115200);
olympux 4:568c97f2a407 205
olympux 4:568c97f2a407 206
olympux 4:568c97f2a407 207 /*
olympux 4:568c97f2a407 208 * UI threads
olympux 4:568c97f2a407 209 */
olympux 4:568c97f2a407 210 Thread t1(uart_thread);
olympux 4:568c97f2a407 211
olympux 6:d054e394fba3 212
olympux 6:d054e394fba3 213 /*
olympux 6:d054e394fba3 214 * FLASH
olympux 6:d054e394fba3 215 */
olympux 6:d054e394fba3 216 load_eeprom();
olympux 6:d054e394fba3 217 IP_Addr = ip_addr;
olympux 6:d054e394fba3 218 IP_Subnet = ip_subnet;
olympux 6:d054e394fba3 219 IP_Gateway = ip_gateway;
olympux 6:d054e394fba3 220
olympux 4:568c97f2a407 221
olympux 4:568c97f2a407 222 /*
olympux 4:568c97f2a407 223 * Ethernet
olympux 4:568c97f2a407 224 */
olympux 6:d054e394fba3 225 ret = ethernet_init();
olympux 4:568c97f2a407 226 if (ret) {
olympux 4:568c97f2a407 227 printf("App halted\n");
olympux 4:568c97f2a407 228 while (true) {};
olympux 4:568c97f2a407 229 }
olympux 4:568c97f2a407 230
olympux 3:972ed747474c 231
olympux 3:972ed747474c 232 #ifdef TCP_SERVER
olympux 3:972ed747474c 233 TCPSocketServer tcp_server;
olympux 3:972ed747474c 234 TCPSocketConnection tcp_client;
olympux 3:972ed747474c 235
olympux 6:d054e394fba3 236 tcp_server.bind(tcp_server_port);
olympux 3:972ed747474c 237 tcp_server.listen();
olympux 4:568c97f2a407 238 uart.printf("\nWait for new connection...\n");
olympux 4:568c97f2a407 239 tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
olympux 3:972ed747474c 240 #endif
olympux 3:972ed747474c 241
olympux 3:972ed747474c 242 #ifdef UDP_SERVER
olympux 3:972ed747474c 243 UDPSocket udp_server;
olympux 3:972ed747474c 244 Endpoint ep_udp_client;
olympux 3:972ed747474c 245
olympux 6:d054e394fba3 246 ret = udp_server.bind(udp_server_port);
olympux 4:568c97f2a407 247 printf("sock.bind = %d\n", ret);
olympux 4:568c97f2a407 248 udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
olympux 3:972ed747474c 249 #endif
olympux 3:972ed747474c 250
olympux 3:972ed747474c 251
olympux 4:568c97f2a407 252 // Network processor
olympux 0:c2eac797face 253 while (true) {
olympux 4:568c97f2a407 254 #ifdef TCP_SERVER
olympux 4:568c97f2a407 255 // no tcp client connected
olympux 4:568c97f2a407 256 if (!tcp_client.is_connected())
olympux 4:568c97f2a407 257 {
olympux 4:568c97f2a407 258 // wait for client within timeout
olympux 4:568c97f2a407 259 ret = tcp_server.accept(tcp_client);
olympux 2:18f10e7209f4 260
olympux 4:568c97f2a407 261 // tcp client connected
olympux 4:568c97f2a407 262 if (ret > -1) {
olympux 4:568c97f2a407 263 uart.printf("Connection from: %s\n", tcp_client.get_address());
olympux 4:568c97f2a407 264
olympux 4:568c97f2a407 265 // loop waiting and receiving data within timeout
olympux 4:568c97f2a407 266 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
olympux 4:568c97f2a407 267 while (true) {
olympux 4:568c97f2a407 268 int n = tcp_client.receive(buffer, sizeof(buffer));
olympux 4:568c97f2a407 269 if (n <= 0) break;
olympux 4:568c97f2a407 270
olympux 4:568c97f2a407 271 // got data, process it
olympux 4:568c97f2a407 272 // send to uart
olympux 4:568c97f2a407 273 buffer[n] = '\0';
olympux 4:568c97f2a407 274 message.len = n;
olympux 4:568c97f2a407 275 message.msg = buffer;
olympux 4:568c97f2a407 276 uart_queue.put(&message);
olympux 4:568c97f2a407 277
olympux 4:568c97f2a407 278 // echo to tcp client
olympux 4:568c97f2a407 279 tcp_client.send_all(buffer, n);
olympux 4:568c97f2a407 280 if (n <= 0) break;
olympux 4:568c97f2a407 281 } // end loop if no data received within timeout
olympux 4:568c97f2a407 282 tcp_client.close();
olympux 4:568c97f2a407 283 } // if client connected
olympux 4:568c97f2a407 284 } // if no client connected
olympux 3:972ed747474c 285 #endif
olympux 3:972ed747474c 286
olympux 4:568c97f2a407 287
olympux 3:972ed747474c 288 #ifdef UDP_SERVER
olympux 4:568c97f2a407 289 // wait for udp packet within timeout
olympux 3:972ed747474c 290 int n = udp_server.receiveFrom(ep_udp_client, buffer, sizeof(buffer));
olympux 3:972ed747474c 291 if (n < 0) continue;
olympux 3:972ed747474c 292
olympux 4:568c97f2a407 293 // got some data, process it
olympux 3:972ed747474c 294 // send to uart
olympux 3:972ed747474c 295 buffer[n] = '\0';
olympux 3:972ed747474c 296 message.len = n;
olympux 3:972ed747474c 297 message.msg = buffer;
olympux 3:972ed747474c 298 uart_queue.put(&message);
olympux 3:972ed747474c 299
olympux 3:972ed747474c 300 // echo
olympux 3:972ed747474c 301 //printf("Received packet from: %s\n", client.get_address());
olympux 3:972ed747474c 302 udp_server.sendTo(ep_udp_client, buffer, n);
olympux 4:568c97f2a407 303
olympux 6:d054e394fba3 304 // process received data
olympux 6:d054e394fba3 305 switch (n) {
olympux 6:d054e394fba3 306 // length = 14, maybe this is a command to set network configuration
olympux 6:d054e394fba3 307 // Format: 4E 4E C0 A8 00 78 FF FF FF 00 C0 A8 0 1 (NN 192.168.0.120; 255.255.255.0; 192.168.0.1)
olympux 6:d054e394fba3 308 case 14:
olympux 6:d054e394fba3 309 // check if two first chars = NN
olympux 6:d054e394fba3 310 if (strstr(buffer, "NN") != NULL) {
olympux 6:d054e394fba3 311 printf("Received new network configuration\n");
olympux 6:d054e394fba3 312 write_eeprom(&buffer[2]); // parameters from 3rd char
olympux 6:d054e394fba3 313 }
olympux 6:d054e394fba3 314 break;
olympux 6:d054e394fba3 315 default:
olympux 6:d054e394fba3 316 break;
olympux 4:568c97f2a407 317 }
olympux 3:972ed747474c 318 #endif
olympux 4:568c97f2a407 319 } // network processor
olympux 4:568c97f2a407 320 }