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:
Thu Jun 16 08:38:31 2016 +0000
Revision:
40:c966abbe2d62
Parent:
39:083cf93121a9
Child:
41:a50a534a2fbb
Working with a few issues:; - Added RPC AnalogIn, wdt reset when creating new object on PC_0; - Added creating RPC string but not tested yet

Who changed what in which revision?

UserRevisionLine numberNew 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 40:c966abbe2d62 16 #include "RPCCommand.h"
olympux 40:c966abbe2d62 17 #include "HTTPServer.h"
olympux 40:c966abbe2d62 18 #include "Formatter.h"
olympux 40:c966abbe2d62 19 #include "RequestHandler.h"
olympux 40:c966abbe2d62 20 #include "RPCType.h"
olympux 40:c966abbe2d62 21
olympux 40:c966abbe2d62 22 #define SERVER_PORT 80
olympux 40:c966abbe2d62 23
olympux 0:c2eac797face 24
olympux 31:2e4b6de6c2f3 25 /** Debug option
olympux 31:2e4b6de6c2f3 26 *
olympux 31:2e4b6de6c2f3 27 */
olympux 25:48dd18cc147c 28 #if 1
olympux 16:84a5bf7285d0 29 //Enable debug
olympux 16:84a5bf7285d0 30 #include <cstdio>
olympux 31:2e4b6de6c2f3 31 #define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__);
olympux 31:2e4b6de6c2f3 32 #define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__);
olympux 31:2e4b6de6c2f3 33 #define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__);
olympux 16:84a5bf7285d0 34 #else
olympux 16:84a5bf7285d0 35 //Disable debug
olympux 31:2e4b6de6c2f3 36 #define DBG(x, ...)
olympux 16:84a5bf7285d0 37 #define WARN(x, ...)
olympux 31:2e4b6de6c2f3 38 #define ERR(x, ...)
olympux 16:84a5bf7285d0 39 #endif
olympux 16:84a5bf7285d0 40
olympux 16:84a5bf7285d0 41
olympux 2:18f10e7209f4 42 /*
olympux 2:18f10e7209f4 43 * Hardware defines
olympux 0:c2eac797face 44 */
olympux 9:d2534ecf88c6 45 // Ethernet
olympux 0:c2eac797face 46 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
olympux 11:709f90a3b599 47 EthernetInterface eth(&spi, PA_4, PC_9); // spi, cs, reset
olympux 40:c966abbe2d62 48 int ethernet_init(void);
olympux 30:15e23257e786 49
olympux 30:15e23257e786 50 /*
olympux 30:15e23257e786 51 * EEPROM section
olympux 30:15e23257e786 52 */
olympux 30:15e23257e786 53 // Virtual address defined by the user: 0xFFFF value is prohibited
olympux 30:15e23257e786 54 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
olympux 30:15e23257e786 55 0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
olympux 30:15e23257e786 56 0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
olympux 30:15e23257e786 57 0x4212, // TCP server port, not used
olympux 30:15e23257e786 58 0x5212, // UDP server port, not used
olympux 30:15e23257e786 59 0x8888, // 1st run? 0xA5A5 = configured
olympux 30:15e23257e786 60 0x6212, 0x6313, 0x6414, // MAC
olympux 31:2e4b6de6c2f3 61
olympux 30:15e23257e786 62 // this section is for the TCP server that this device connects to in TCP client mode
olympux 30:15e23257e786 63 0x7212, 0x7313, // 0xA5A5 = auto transmit status, time period
olympux 30:15e23257e786 64 0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
olympux 30:15e23257e786 65 0x9212, // TCP server port
olympux 31:2e4b6de6c2f3 66
olympux 30:15e23257e786 67 // this section is for selecting protocol, not used
olympux 30:15e23257e786 68 0xA212, // 0xA5A5 = enable TCP server
olympux 30:15e23257e786 69 0xA313, // 0xA5A5 = eanble TCP client
olympux 30:15e23257e786 70 0xA414 // 0xA5A5 = enable UDP server
olympux 31:2e4b6de6c2f3 71 };
olympux 31:2e4b6de6c2f3 72
olympux 30:15e23257e786 73
olympux 30:15e23257e786 74 /*
olympux 30:15e23257e786 75 * Variables for network configuration, TCP server
olympux 30:15e23257e786 76 */
olympux 30:15e23257e786 77 uint8_t u8mac[6], u8ip_addr[4];// keep mac and ip address in 8-bits
olympux 30:15e23257e786 78 uint16_t u16mac_addr[3], u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // 16-bits, directly loaded from eeprom
olympux 30:15e23257e786 79 char str_ip_addr[16], str_ip_subnet[16], str_ip_gateway[16]; // for printf, converted from 16-bits u16ip_xxx
olympux 30:15e23257e786 80 uint16_t configured_ip = 0; // static ip configured flag
olympux 30:15e23257e786 81
olympux 30:15e23257e786 82 const uint16_t tcp_server_local_port = 10000; // fixed, change to 7000 if internet required
olympux 30:15e23257e786 83 const uint16_t udp_server_local_port = 11000; // fixed
olympux 30:15e23257e786 84
olympux 30:15e23257e786 85 // TCP client: this section is used for the TCP server that this device connects to in TCP client mode
olympux 30:15e23257e786 86 // this device will transmit status every transmit_time_period
olympux 30:15e23257e786 87 uint16_t auto_transmit_flag = 0, transmit_time_period = 1000; // auto transmit status, time period = 1s
olympux 30:15e23257e786 88 uint16_t u16server_ip_addr[4]; // directly loaded from eeprom
olympux 30:15e23257e786 89 uint8_t u8server_ip_addr[4]; // server ip address in 8-bits
olympux 30:15e23257e786 90 char str_server_ip_addr[16];// for printf, converted from 16-bits u16server_ip_addr
olympux 30:15e23257e786 91 uint16_t u16tcp_server_port; // directly loaded from eeprom
olympux 30:15e23257e786 92 uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
olympux 30:15e23257e786 93
olympux 30:15e23257e786 94
olympux 27:22f289beceb8 95 // Serial
olympux 27:22f289beceb8 96 Serial uart(USBTX,USBRX);
olympux 20:71c7950fdd91 97 // Watchdog
olympux 20:71c7950fdd91 98 Watchdog wdt;
olympux 20:71c7950fdd91 99
olympux 40:c966abbe2d62 100 float speed;
olympux 40:c966abbe2d62 101 RPCVariable<float> rpcSpeed(&speed, "speed");
olympux 40:c966abbe2d62 102 char stripaddr[20];
olympux 40:c966abbe2d62 103 RPCVariable<char*> rpcIPAddress(stripaddr, "ipaddr");
olympux 26:09e0dd020900 104
olympux 26:09e0dd020900 105
olympux 2:18f10e7209f4 106 /*
olympux 2:18f10e7209f4 107 * Threads
olympux 2:18f10e7209f4 108 */
olympux 20:71c7950fdd91 109 // WDT reset
olympux 31:2e4b6de6c2f3 110 void wdt_reset_thread(void const* args)
olympux 31:2e4b6de6c2f3 111 {
olympux 20:71c7950fdd91 112 while (true)
olympux 20:71c7950fdd91 113 wdt.Service();
olympux 20:71c7950fdd91 114 }
olympux 20:71c7950fdd91 115
olympux 40:c966abbe2d62 116
olympux 40:c966abbe2d62 117 HTTPServer create_simple_server()
olympux 40:c966abbe2d62 118 {
olympux 40:c966abbe2d62 119 HTTPServer srv;
olympux 40:c966abbe2d62 120 srv.add_request_handler("DELETE", new DeleteRequestHandler());
olympux 40:c966abbe2d62 121 srv.add_request_handler("GET", new GetRequestHandler());
olympux 40:c966abbe2d62 122 srv.add_request_handler("PUT", new PutRequestHandler());
olympux 40:c966abbe2d62 123 return srv;
olympux 40:c966abbe2d62 124 }
olympux 40:c966abbe2d62 125
olympux 40:c966abbe2d62 126 HTTPServer create_interactive_server()
olympux 39:083cf93121a9 127 {
olympux 40:c966abbe2d62 128 HTTPServer srv(new InteractiveHTMLFormatter());
olympux 40:c966abbe2d62 129 srv.add_request_handler("GET", new ComplexRequestHandler());
olympux 40:c966abbe2d62 130 return srv;
olympux 38:f8735ae519aa 131 }
olympux 38:f8735ae519aa 132
olympux 38:f8735ae519aa 133 // Main code
olympux 4:568c97f2a407 134 int main()
olympux 4:568c97f2a407 135 {
olympux 9:d2534ecf88c6 136 int n, ret;
olympux 31:2e4b6de6c2f3 137
olympux 20:71c7950fdd91 138 Thread::wait(500); // turn on delay
olympux 31:2e4b6de6c2f3 139
olympux 4:568c97f2a407 140 /*
olympux 9:d2534ecf88c6 141 * Configure
olympux 4:568c97f2a407 142 */
olympux 11:709f90a3b599 143 uart.baud(115200);
olympux 36:dc6f079777bb 144 DBG("Starting...");
olympux 31:2e4b6de6c2f3 145
olympux 31:2e4b6de6c2f3 146 // check watchdog
olympux 20:71c7950fdd91 147 if (wdt.WatchdogCausedReset())
olympux 20:71c7950fdd91 148 DBG("Watchdog caused reset.");
olympux 20:71c7950fdd91 149 wdt.Configure(4);
olympux 31:2e4b6de6c2f3 150
olympux 6:d054e394fba3 151 /*
olympux 6:d054e394fba3 152 * FLASH
olympux 6:d054e394fba3 153 */
olympux 12:7c152c0ca4d8 154 load_eeprom_network();
olympux 15:edeb0aed160d 155 load_eeprom_tcpserver();
olympux 31:2e4b6de6c2f3 156
olympux 20:71c7950fdd91 157 /*
olympux 20:71c7950fdd91 158 * UI threads
olympux 20:71c7950fdd91 159 */
olympux 20:71c7950fdd91 160 Thread t3(wdt_reset_thread);
olympux 40:c966abbe2d62 161
olympux 40:c966abbe2d62 162 // rpc
olympux 40:c966abbe2d62 163 RPCType::instance().register_types();
olympux 31:2e4b6de6c2f3 164
olympux 4:568c97f2a407 165 /*
olympux 4:568c97f2a407 166 * Ethernet
olympux 4:568c97f2a407 167 */
olympux 6:d054e394fba3 168 ret = ethernet_init();
olympux 4:568c97f2a407 169 if (ret) {
olympux 18:ca499a2e7da6 170 ERR("Ethernet initialisation failed. App halted.");
olympux 4:568c97f2a407 171 while (true) {};
olympux 4:568c97f2a407 172 }
olympux 31:2e4b6de6c2f3 173
olympux 23:47ee805435b1 174 Thread::wait(2000); // TCP/UDP stack delay
olympux 40:c966abbe2d62 175
olympux 40:c966abbe2d62 176 // Test parsing ip address string
olympux 40:c966abbe2d62 177 char* ipaddr = "192.168.0.121";
olympux 40:c966abbe2d62 178 int b[4];
olympux 40:c966abbe2d62 179 sscanf(ipaddr, "%d.%d.%d.%d", &b[0], &b[1], &b[2], &b[3]);
olympux 40:c966abbe2d62 180 DBG("%d.%d.%d.%d",b[0],b[1],b[2],b[3]);
olympux 31:2e4b6de6c2f3 181
olympux 40:c966abbe2d62 182 // create rpc http server
olympux 40:c966abbe2d62 183 HTTPServer srv = create_interactive_server();
olympux 26:09e0dd020900 184
olympux 40:c966abbe2d62 185 if(!srv.init(SERVER_PORT))
olympux 40:c966abbe2d62 186 {
olympux 40:c966abbe2d62 187 eth.disconnect();
olympux 40:c966abbe2d62 188 return -1;
olympux 27:22f289beceb8 189 }
olympux 31:2e4b6de6c2f3 190
olympux 40:c966abbe2d62 191 srv.run();
olympux 26:09e0dd020900 192 }
olympux 26:09e0dd020900 193
olympux 26:09e0dd020900 194
olympux 26:09e0dd020900 195 /*
olympux 26:09e0dd020900 196 * W5500 Ethernet init
olympux 26:09e0dd020900 197 */
olympux 31:2e4b6de6c2f3 198 int ethernet_init(void)
olympux 31:2e4b6de6c2f3 199 {
olympux 26:09e0dd020900 200 int dhcp_ret, ret;
olympux 31:2e4b6de6c2f3 201
olympux 27:22f289beceb8 202 DBG("Initialising ethernet...");
olympux 31:2e4b6de6c2f3 203
olympux 26:09e0dd020900 204 // if not configured, try dhcp
olympux 26:09e0dd020900 205 dhcp_ret = -1;
olympux 26:09e0dd020900 206 if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
olympux 27:22f289beceb8 207 DBG("Connecting to DHCP server...");
olympux 26:09e0dd020900 208 dhcp_ret = eth.init(u8mac);
olympux 26:09e0dd020900 209 if (dhcp_ret == 0)
olympux 26:09e0dd020900 210 dhcp_ret = eth.connect();
olympux 26:09e0dd020900 211 }
olympux 31:2e4b6de6c2f3 212
olympux 26:09e0dd020900 213 if (dhcp_ret != 0) {
olympux 26:09e0dd020900 214 DBG("No DHCP, load static IP configuration");
olympux 26:09e0dd020900 215 ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
olympux 26:09e0dd020900 216 } else {
olympux 26:09e0dd020900 217 snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
olympux 26:09e0dd020900 218 snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
olympux 26:09e0dd020900 219 snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
olympux 26:09e0dd020900 220 ret = 0;
olympux 26:09e0dd020900 221 }
olympux 26:09e0dd020900 222
olympux 26:09e0dd020900 223 if (ret == 0) {
olympux 26:09e0dd020900 224 DBG("Initialized, MAC: %s", eth.getMACAddress());
olympux 26:09e0dd020900 225 } else {
olympux 26:09e0dd020900 226 ERR("Error eth.init() - ret = %d", ret);
olympux 26:09e0dd020900 227 return -1;
olympux 26:09e0dd020900 228 }
olympux 26:09e0dd020900 229
olympux 26:09e0dd020900 230 ret = eth.connect();
olympux 26:09e0dd020900 231 if (!ret) {
olympux 26:09e0dd020900 232 DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
olympux 26:09e0dd020900 233 } else {
olympux 26:09e0dd020900 234 ERR("Error eth.connect() - ret = %d", ret);
olympux 26:09e0dd020900 235 return -1;
olympux 26:09e0dd020900 236 }
olympux 31:2e4b6de6c2f3 237
olympux 26:09e0dd020900 238 return 0;
olympux 26:09e0dd020900 239 }
olympux 26:09e0dd020900 240