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

Revision:
9:d2534ecf88c6
Parent:
8:64848959adb9
Child:
10:4cd965d79de0
--- a/main.cpp	Sun Sep 21 20:25:35 2014 +0000
+++ b/main.cpp	Fri Sep 26 20:07:34 2014 +0000
@@ -6,6 +6,7 @@
 #include "mbed.h"
 //#include "eeprom.h"
 #include "EthernetInterface.h"
+#include "NTPClient.h"
 #include "rtos.h"
 
 
@@ -15,22 +16,38 @@
 #define ST_NUCLEO // hardware pin mapping
 
 #ifdef ST_NUCLEO
-// ST Nucleo
+// Ethernet
 SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
 EthernetInterface eth(&spi, PC_8, PC_9); // spi, cs, reset
 #endif
 
+// Serial
 Serial uart(USBTX,USBRX);
 
-// Variables' number
-#define NumbOfVar         ((uint8_t)0x0F) // REMEMBER: update this variable in eeprom.h too
+// Digital inputs
+// Digital outputs
+// Analog inputs
+// Analog outputs
+//AnalogOut ano0(p18);
+
+
+// eeprom
+#define NumbOfVar         ((uint8_t)0x80) // REMEMBER: update this variable in eeprom.h too
+#define IP_ADDRESS_POS         0
+#define IP_SUBNET_POS          4
+#define IP_GATEWAY_POS         8
+#define TCP_SERVER_PORT_POS    12
+#define UDP_SERVER_PORT_POS    13
+#define FIRST_RUN_FLAG_POS     14
+#define MAC_ADDRESS_POS        15
 // Virtual address defined by the user: 0xFFFF value is prohibited
 uint16_t VirtAddVarTab[NumbOfVar] = {0x1212, 0x1313, 0x1414, 0x1515, // IP_Addr
                                      0x2212, 0x2313, 0x2414, 0x2515, // IP_Subnet
                                      0x3212, 0x3313, 0x3414, 0x3515, // IP_Gateway
                                      0x4212, // TCP server port, not used
                                      0x5212, // UDP server port, not used
-                                     0x8888  // 1st run? 
+                                     0x8888,  // 1st run? 
+                                     0x6212, 0x6313, 0x6414 // MAC
                                      };
 extern "C" uint16_t EE_Init(void);
 extern "C" uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
@@ -49,22 +66,56 @@
 #define DEFAULT_IP_ADDRESS      "192.168.0.249"
 #define DEFAULT_IP_SUBNET       "255.255.255.0"
 #define DEFAULT_IP_GATEWAY      "192.168.0.1"
+#define DEFAULT_MAC3            0x00
+#define DEFAULT_MAC4            0x00
+#define DEFAULT_MAC5            0x01
 
 #define TCP_SERVER_WAIT_CLIENT_TIMEOUT     200
 #define TCP_SERVER_RECEIVE_TIMEOUT         3000
 #define UDP_SERVER_RECEIVE_TIMEOUT         200
 
 // for static IP setting
-char * IP_Addr;
+uint8_t mac[6];
+char * IP_Addr; // pointers to 
 char * IP_Subnet;
 char * IP_Gateway;
-char   ip_addr[16], ip_subnet[16], ip_gateway[16]; // loaded from eeprom
 
-uint16_t tcp_server_port = 10000; // fixed
-uint16_t udp_server_port = 11000; // fixed
+uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4]; // directly loaded from eeprom
+uint16_t first_run = 0;  // first run flag
+uint16_t u16mac_addr[3]; // loaded from eeprom
+char   ip_addr[16], ip_subnet[16], ip_gateway[16]; // chars, converted from u16ip_xxx
+
+const uint16_t tcp_server_port = 10000; // fixed
+const uint16_t udp_server_port = 11000; // fixed
 
 char buffer[256]; // socket buffer
 
+NTPClient ntp;
+
+// Commands
+#define DEVICE_ID                   "NNIO"
+#define DISCOVERY_COMMAND           "NNIODS"
+#define TCP_SERVER_PORT_COMAMND     "NNIOTP"
+#define UDP_SERVER_PORT_COMAMND     "NNIOUP"
+#define QUERY_STATUS_COMMAND        (uint8_t)'Q'
+
+
+// Positions
+#define RECEIVING_PROTOCOL_OP_POS           4
+#define RECEIVING_PROTOCOL_EN_DO_POS        RECEIVING_PROTOCOL_OP_POS + 0
+#define RECEIVING_PROTOCOL_EN_A0O_POS       RECEIVING_PROTOCOL_OP_POS + 1
+#define RECEIVING_PROTOCOL_EN_A1O_POS       RECEIVING_PROTOCOL_OP_POS + 2
+#define RECEIVING_PROTOCOL_EN_UART_POS      RECEIVING_PROTOCOL_OP_POS + 3
+#define RECEIVING_PROTOCOL_COMMAND_POS      RECEIVING_PROTOCOL_OP_POS + 4
+#define RECEIVING_PROTOCOL_ENABLE_OUTPUT    (uint8_t)'O'
+
+
+#define RECEIVING_PROTOCOL_POS_IP           9
+#define RECEIVING_PROTOCOL_POS_DO           13
+#define RECEIVING_PROTOCOL_POS_A0O          21
+#define RECEIVING_PROTOCOL_POS_A01          23
+#define RECEIVING_PROTOCOL_POS_UART         25
+
 
 
 /*
@@ -102,17 +153,11 @@
 * Ethernet init
 */
 int ethernet_init(void) {
-    uint8_t mac[6];
-        
-    mbed_mac_address((char *)mac);     // using the MAC address in LPC11U24 or LPC1178
-    mac[0] = 0x00; mac[1] = 0x08; mac[2] = 0xDC; mac[3] = 0x00; mac[4] = 0x00; mac[5] = 0x00; 
-    
-    
     //printf("Start\n");
     int ret = eth.init(mac, IP_Addr, IP_Subnet, IP_Gateway); // static
 
     if (!ret) {
-        //uart.printf("Initialized, MAC: %s\n", eth.getMACAddress());
+        uart.printf("Initialized, MAC: %s\n", eth.getMACAddress());
     } else {
         uart.printf("Error eth.init() - ret = %d\n", ret);
         return -1;
@@ -134,72 +179,98 @@
 * EEPROM functions
 */
 void write_eeprom(char *buffer) {
+    // Write network configuration
+    // 4-byte IP address + 4-byte subnet + 4-byte gateway + 3-byte MAC
+    
     // Unlock the Flash Program Erase controller */
     FLASH_Unlock();
     // EEPROM Init
     EE_Init();
     // IP address
-    EE_WriteVariable(VirtAddVarTab[0], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[1], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[2], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[3], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_ADDRESS_POS+0], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_ADDRESS_POS+1], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_ADDRESS_POS+2], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_ADDRESS_POS+3], *buffer++);
+    
     // IP subnet
-    EE_WriteVariable(VirtAddVarTab[4], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[5], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[6], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[7], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_SUBNET_POS+0], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_SUBNET_POS+1], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_SUBNET_POS+2], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_SUBNET_POS+3], *buffer++);
+    
     // IP gateway
-    EE_WriteVariable(VirtAddVarTab[8], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[9], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[10], *buffer++);
-    EE_WriteVariable(VirtAddVarTab[11], *buffer++);
-    //// TCP server port
-    //EE_WriteVariable(VirtAddVarTab[12], *buffer++);
-    //// UDP server port
-    //EE_WriteVariable(VirtAddVarTab[13], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_GATEWAY_POS+0], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_GATEWAY_POS+1], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_GATEWAY_POS+2], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[IP_GATEWAY_POS+3], *buffer++);
+    
+    //// TCP server port, not used
+    //EE_WriteVariable(VirtAddVarTab[TCP_SERVER_PORT_POS], *buffer++);
+    //// UDP server port, not used
+    //EE_WriteVariable(VirtAddVarTab[UDP_SERVER_PORT_POS], *buffer++);
     
     // erase first_run flag
-    EE_WriteVariable(VirtAddVarTab[14], 0xA5A5);
+    EE_WriteVariable(VirtAddVarTab[FIRST_RUN_FLAG_POS], 0xA5A5);
+    
+    // MAC address
+    EE_WriteVariable(VirtAddVarTab[MAC_ADDRESS_POS+0], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[MAC_ADDRESS_POS+1], *buffer++);
+    EE_WriteVariable(VirtAddVarTab[MAC_ADDRESS_POS+2], *buffer++);
     FLASH_Lock();
 }
 
 
 void load_eeprom(void) {
-    uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4];
-    uint16_t first_run = 0;
+    mbed_mac_address((char *)mac);
     
     EE_Init();
     
     // check if 1st run
-    EE_ReadVariable(VirtAddVarTab[14], &first_run);
+    EE_ReadVariable(VirtAddVarTab[FIRST_RUN_FLAG_POS], &first_run);
     // if not first run, load network config
     if (first_run == 0xA5A5) {
         // IP address
-        EE_ReadVariable(VirtAddVarTab[0], &u16ip_addr[0]);
-        EE_ReadVariable(VirtAddVarTab[1], &u16ip_addr[1]);
-        EE_ReadVariable(VirtAddVarTab[2], &u16ip_addr[2]);
-        EE_ReadVariable(VirtAddVarTab[3], &u16ip_addr[3]);
+        EE_ReadVariable(VirtAddVarTab[IP_ADDRESS_POS+0], &u16ip_addr[0]);
+        EE_ReadVariable(VirtAddVarTab[IP_ADDRESS_POS+1], &u16ip_addr[1]);
+        EE_ReadVariable(VirtAddVarTab[IP_ADDRESS_POS+2], &u16ip_addr[2]);
+        EE_ReadVariable(VirtAddVarTab[IP_ADDRESS_POS+3], &u16ip_addr[3]);
+        
         // IP subnet
-        EE_ReadVariable(VirtAddVarTab[4], &u16ip_subnet[0]);
-        EE_ReadVariable(VirtAddVarTab[5], &u16ip_subnet[1]);
-        EE_ReadVariable(VirtAddVarTab[6], &u16ip_subnet[2]);
-        EE_ReadVariable(VirtAddVarTab[7], &u16ip_subnet[3]);
+        EE_ReadVariable(VirtAddVarTab[IP_SUBNET_POS+0], &u16ip_subnet[0]);
+        EE_ReadVariable(VirtAddVarTab[IP_SUBNET_POS+1], &u16ip_subnet[1]);
+        EE_ReadVariable(VirtAddVarTab[IP_SUBNET_POS+2], &u16ip_subnet[2]);
+        EE_ReadVariable(VirtAddVarTab[IP_SUBNET_POS+3], &u16ip_subnet[3]);
+        
         // IP gateway
-        EE_ReadVariable(VirtAddVarTab[8], &u16ip_gateway[0]);
-        EE_ReadVariable(VirtAddVarTab[9], &u16ip_gateway[1]);
-        EE_ReadVariable(VirtAddVarTab[10], &u16ip_gateway[2]);
-        EE_ReadVariable(VirtAddVarTab[11], &u16ip_gateway[3]);
+        EE_ReadVariable(VirtAddVarTab[IP_GATEWAY_POS+0], &u16ip_gateway[0]);
+        EE_ReadVariable(VirtAddVarTab[IP_GATEWAY_POS+1], &u16ip_gateway[1]);
+        EE_ReadVariable(VirtAddVarTab[IP_GATEWAY_POS+2], &u16ip_gateway[2]);
+        EE_ReadVariable(VirtAddVarTab[IP_GATEWAY_POS+3], &u16ip_gateway[3]);
+        
         //// TCP server port
-        //EE_ReadVariable(VirtAddVarTab[12], &tcp_server_port);
+        //EE_ReadVariable(VirtAddVarTab[TCP_SERVER_PORT_POS], &tcp_server_port);
         //// UDP server port
-        //EE_ReadVariable(VirtAddVarTab[13], &udp_server_port);
+        //EE_ReadVariable(VirtAddVarTab[UDP_SERVER_PORT_POS], &udp_server_port);
+        
+        // First run flag, already read above
+
+        // MAC address
+        EE_ReadVariable(VirtAddVarTab[MAC_ADDRESS_POS+0], &u16mac_addr[0]);
+        EE_ReadVariable(VirtAddVarTab[MAC_ADDRESS_POS+1], &u16mac_addr[1]);
+        EE_ReadVariable(VirtAddVarTab[MAC_ADDRESS_POS+2], &u16mac_addr[2]);
+        mac[3] = (uint8_t)(u16mac_addr[0] & 0x00FF);
+        mac[4] = (uint8_t)(u16mac_addr[1] & 0x00FF);
+        mac[5] = (uint8_t)(u16mac_addr[2] & 0x00FF);
         //FLASH_Lock();
+        
         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]);
         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]);
         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]);
     }
     // if 1st run, use default addresses
     else {
+        mac[0] = 0x00; mac[1] = 0x08; mac[2] = 0xDC;
+        mac[3] = DEFAULT_MAC3; mac[4] = DEFAULT_MAC4; mac[5] = DEFAULT_MAC5; 
         sprintf(ip_addr, DEFAULT_IP_ADDRESS);
         sprintf(ip_subnet, DEFAULT_IP_SUBNET);
         sprintf(ip_gateway, DEFAULT_IP_GATEWAY);
@@ -216,12 +287,12 @@
 int main()
 {
     message_t message;
-    int ret;
+    int n, ret;
     
     /*
-    * configure
+    * Configure
     */
-    uart.baud(115200);
+    //uart.baud(115200);
     
   
     /*
@@ -271,6 +342,23 @@
 
     // Network processor
     while (true) {
+#ifdef NTP
+        printf("Trying to update time...\r\n");
+        if (ntp.setTime("0.pool.ntp.org") == 0)
+        {
+          printf("Set time successfully\r\n");
+          time_t ctTime;
+          ctTime = time(NULL);
+          printf("Time is set to (UTC): %s\r\n", ctime(&ctTime));
+        }
+        else
+        {
+          printf("Error\r\n");
+        }
+#endif
+
+        
+// FOR INTERFACING
 #ifdef TCP_SERVER
         // no tcp client connected
         if (!tcp_client.is_connected())
@@ -285,73 +373,117 @@
                 // loop waiting and receiving data within timeout
                 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
                 while (true) {
-                    int n = tcp_client.receive(buffer, sizeof(buffer));
+                    n = tcp_client.receive(buffer, sizeof(buffer));
                     if (n <= 0) break;
                     
-                    // got data, process it
-                    // send to uart
-                    buffer[n] = '\0';
-                    message.len = n;
-                    message.msg = buffer;
-                    uart_queue.put(&message);
+                    // got some data, test it
+                    //// send to uart
+                    //buffer[n] = '\0';
+                    //message.len = n;
+                    //message.msg = buffer;
+                    //uart_queue.put(&message);
+                    //// echo to tcp client
+                    //tcp_client.send_all(buffer, n);
+                    //if (n <= 0) break;
                     
-                    // echo to tcp client
-                    tcp_client.send_all(buffer, n);
-                    if (n <= 0) break;
+                    // process received data
+                    switch (n) {
+                        // length 58-bytes, Receiving protocol
+                        case 58: {
+                            // check device id
+                            char* id = strstr(buffer, DEVICE_ID);
+                            if (id == NULL)
+                                break;
+                            else if ((id - buffer) > 0)
+                                break;
+                            
+                            
+                            // firstly, update outputs if required
+                            // digital outputs
+                            if (((uint8_t)buffer[RECEIVING_PROTOCOL_EN_DO_POS] - RECEIVING_PROTOCOL_ENABLE_OUTPUT) == 0) {
+                            }
+                            // analog output 0
+                            if (((uint8_t)buffer[RECEIVING_PROTOCOL_EN_A0O_POS] - RECEIVING_PROTOCOL_ENABLE_OUTPUT) == 0) {
+                            }
+                            // analog output 0
+                            if (((uint8_t)buffer[RECEIVING_PROTOCOL_EN_A1O_POS] - RECEIVING_PROTOCOL_ENABLE_OUTPUT) == 0) {
+                            }
+                            // UART
+                            if (((uint8_t)buffer[RECEIVING_PROTOCOL_EN_UART_POS] - RECEIVING_PROTOCOL_ENABLE_OUTPUT) == 0) {
+                            }
+                            
+                            // then, check query status command and sending protocol if required
+                            if (((uint8_t)buffer[RECEIVING_PROTOCOL_COMMAND_POS] - QUERY_STATUS_COMMAND) == 0) {
+                                // sending protocol
+                            }
+                            
+                            break;
+                        }
+                        default:
+                            break;
+                    }
+                    
                 } // end loop if no data received within timeout
                 tcp_client.close();
             } // if client connected
         } // if no client connected
 #endif
     
-
-#ifdef UDP_SERVER // used for setting configuration
+    
+    
+// ONLY FOR CONFIGRATION
+#ifdef UDP_SERVER
         // wait for udp packet within timeout
-        int n = udp_server.receiveFrom(ep_udp_client, buffer, sizeof(buffer));
-        if (n < 0) continue;
+        n = udp_server.receiveFrom(ep_udp_client, buffer, sizeof(buffer));
+        if (n <= 0) continue;
 
-        // got some data, process it
-        // send to uart
+        // got some data, test it
+        //// send to uart
         //buffer[n] = '\0';
         //message.len = n;
         //message.msg = buffer;
         //uart_queue.put(&message);
-            
-        // echo
+        //// echo
         //printf("Received packet from: %s\n", client.get_address());
         //udp_server.sendTo(ep_udp_client, buffer, n);
         
         // process received data
         switch (n) {
-            // length = 4, may be this is a discovery command, TCP port, or UDP port
-            // Format: NNDS, NNTP or NNUP
-            case 4:
+            // length = 6, a CONFIGURATION command (discovery command, TCP port, or UDP port)
+            // Format: NNIODS, NNIOTP or NNIOUP
+            case 6:
                 // discovery command
-                if (strstr(buffer, "NNDS") != NULL) {
+                if (strstr(buffer, "NNIODS") != NULL) {
                     udp_server.sendTo(ep_udp_client, ip_addr, strlen(ip_addr));
                 }
                 // ask for TCP server port
-                else if (strstr(buffer, "NNTP") != NULL) {
+                else if (strstr(buffer, "NNIOTP") != NULL) {
                     char port[5];
                     sprintf(port, "%5d", tcp_server_port);
                     udp_server.sendTo(ep_udp_client, port, strlen(port));
                 }
                 // ask for UDP server port
-                else if (strstr(buffer, "NNUP") != NULL) {
+                else if (strstr(buffer, "NNIOUP") != NULL) {
                     char port[5];
                     sprintf(port, "%5d", udp_server_port);
                     udp_server.sendTo(ep_udp_client, port, strlen(port));
                 }
                 break;
-            // length = 14, maybe this is a command to set network configuration
-            // 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)
-            case 14:
-                // check if two first chars = NN
-                if (strstr(buffer, "NN") != NULL) {
-                    //printf("Received new network configuration\n");
-                    write_eeprom(&buffer[2]); // parameters from 3rd char
-                }
+            // length = 19, SET NETWORK CONFIGURATION
+            // Format: 4E 4E 49 4F      C0 A8 00 78        FF FF FF 00            C0 A8 00 01      00 00 01
+            //        (NNIO;            IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
+            case 19:{
+                // check device id
+                char* id = strstr(buffer, DEVICE_ID);
+                if (id == NULL)
+                    break;
+                else if ((id - buffer) > 0)
+                    break;
+
+                //printf("Received new network configuration\n");
+                write_eeprom(&buffer[4]); // parameters from 3rd char, 15-bytes
                 break;
+            }
             default:
                 break;
         }