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
Revision 9:d2534ecf88c6, committed 2014-09-26
- Comitter:
- olympux
- Date:
- Fri Sep 26 20:07:34 2014 +0000
- Parent:
- 8:64848959adb9
- Child:
- 10:4cd965d79de0
- Commit message:
- Added & tested NTP
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NTPClient.lib Fri Sep 26 20:07:34 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/ban4jp/code/NTPClient/#c70ed0bfab2e
--- a/eeprom.lib Sun Sep 21 20:25:35 2014 +0000 +++ b/eeprom.lib Fri Sep 26 20:07:34 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/olympux/code/eeprom/#5da14988d0e5 +http://mbed.org/users/olympux/code/eeprom/#4bf7c01c5a48
--- 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; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readme.txt Fri Sep 26 20:07:34 2014 +0000 @@ -0,0 +1,63 @@ +CONFIGURATION SECTION (UDP) +1. DISCOVERY Command + + UDP broadcast: 192.168.0.255 to port 11000 + + Send: NNIODS + + Receive: IP address + +2. TCP SERVER PORT Command + + Send: NNIOTP + + Receive: 10000 + +3. UDP SERVER PORT Command + + Send: NNIOUP + + Receive: 11000 + +3. Set new network configuration + + Send: 19 bytes in total, NNIO + 15-byte + 15-byte = 4-byte IP address + 4-byte subnet + 4-byte gateway + 3-byte MAC + +INTERFACING SECTION (TCP) +4. Receiving Protocol: 58-bytes in total + + Field ID (4-bytes) = NNIO + + Field OP (5-bytes): output control enable flag + Byte 1: Digital output + Byte 2: Analog output 0 + Byte 3: Analog output 1 + Byte 4: UART output + Byte 5: Command (Q: query status) + 'O': enable controlling output + Others: disable controlling output + If Command is 'Q', device will update its outputs if needed and send its status including new outputs + + Field IP (4-bytes): device IP address + + Field DO[n] (8-bytes): digital output values + 'H': output set to high + 'L': output set to low + + Field AO_0 (2-bytes): 16-bit analog output value, channel 0 + Range is from 0x0000 to 0x0FFF + + Field AO_1 (2-bytes): 16-bit analog output value, channel 1 + Range is from 0x0000 to 0x0FFF + + UART output (32-bytes): max 32 bytes, stop string by NULL + + End char: CR + +5. Sending Protocol: 39-bytes in total + + Field ID (4-bytes) = NNIO + + Field MAC (6-bytes) + + Field IP (4-bytes) + + Field DI[n]: 8-bit digital input values + 'H' if input is HIGH + 'L' if input is LOW + + Field DO[n]: 8-bit digital output values + 'H' if output is HIGH + 'L' if output is LOW + + Field AI_0 (2-bytes): analog 16-bit input value, channel 0 + Range is from 0x0000 to 0x0FFF + + Field AI_1 (2-bytes): analog 16-bit input value, channel 1 + Range is from 0x0000 to 0x0FFF + + Field AO_0 (2-bytes): 16-bit analog output value, channel 0 + Range is from 0x0000 to 0x0FFF + + Field AO_1 (2-bytes): 16-bit analog output value, channel 1 + Range is from 0x0000 to 0x0FFF + + End char: CR + +6 Commands: + + QUERY STATUS ('Q') \ No newline at end of file