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

main.cpp

Committer:
olympux
Date:
2014-09-21
Revision:
7:d45bd480e90f
Parent:
6:d054e394fba3
Child:
8:64848959adb9

File content as of revision 7:d45bd480e90f:

/*
*
*  Alarm and Monitoring application

*/
#include "mbed.h"
//#include "eeprom.h"
#include "EthernetInterface.h"
#include "rtos.h"


/*
* Hardware defines
*/
#define ST_NUCLEO // hardware pin mapping

#ifdef ST_NUCLEO
// ST Nucleo
SPI spi(PA_7, PA_6, PA_5); // mosi, miso, sclk
EthernetInterface eth(&spi, PC_8, PC_9); // spi, cs, reset
#endif

Serial uart(USBTX,USBRX);

// Variables' number
#define NumbOfVar         ((uint8_t)0x0E) // REMEMBER: update this variable in eeprom.h too
// 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
                                     };
extern "C" uint16_t EE_Init(void);
extern "C" uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
extern "C" uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);


/*
* Network configuration
*/
#define TCP_SERVER
//#define TCP_CLIENT
#define UDP_SERVER
//#define UDP_CLIENT
//#define NTP

#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;
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

char buffer[256]; // socket buffer



/*
* RTOS
*/
struct message_t {
    int len;
    char *msg;
};
Queue<message_t, 16> uart_queue;

Mutex uart_mutex;


/*
* Threads
*/
void uart_thread(void const *args) {
    message_t *p_message;
    
    while (true) {
        osEvent evt = uart_queue.get();
        if (evt.status == osEventMessage) {
            p_message = (message_t*)evt.value.p;
            uart_mutex.lock();
            //uart.printf("len=%d\n", p_message->len);
            uart.printf("%s\n", p_message->msg);
            uart_mutex.unlock();
        }
    }
}


/*
* 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());
    } else {
        uart.printf("Error eth.init() - ret = %d\n", ret);
        return -1;
    }

    ret = eth.connect();
    if (!ret) {
        //uart.printf("IP: %s, MASK: %s, GW: %s\n", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
    } else {
        uart.printf("Error eth.connect() - ret = %d\n", ret);
        return -1;
    }
    
    return 0;
}


/*
* EEPROM functions
*/
void write_eeprom(char *buffer) {
    // 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++);
    // IP subnet
    EE_WriteVariable(VirtAddVarTab[4], *buffer++);
    EE_WriteVariable(VirtAddVarTab[5], *buffer++);
    EE_WriteVariable(VirtAddVarTab[6], *buffer++);
    EE_WriteVariable(VirtAddVarTab[7], *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++);
    FLASH_Lock();
}


void load_eeprom(void) {
    // Load IP adddress
    uint16_t u16ip_addr[4], u16ip_subnet[4], u16ip_gateway[4];
    //FLASH_Unlock();
    EE_Init();
    // 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]);
    // 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]);
    // 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]);
    //// TCP server port
    //EE_ReadVariable(VirtAddVarTab[12], &tcp_server_port);
    //// UDP server port
    //EE_ReadVariable(VirtAddVarTab[13], &udp_server_port);
    //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]);
    //printf("IP: %s\n", ip_addr);
    //printf("MASK: %s\n", ip_subnet);
    //printf("GW: %s\n", ip_gateway);
    //printf("TCP: %d\n", tcp_server_port);
    //printf("UDP: %d\n", udp_server_port);
}



int main()
{
    message_t message;
    int ret;
    
    /*
    * configure
    */
    uart.baud(115200);
    
  
    /*
    * UI threads
    */
    Thread t1(uart_thread);
    
    
    /*
    * FLASH
    */
    load_eeprom();
    IP_Addr = ip_addr;
    IP_Subnet = ip_subnet;
    IP_Gateway = ip_gateway;
    
        
    /*
    * Ethernet
    */
    ret = ethernet_init();
    if (ret) {
        printf("App halted\n");
        while (true) {};
    }
    
        
#ifdef TCP_SERVER
    TCPSocketServer tcp_server;
    TCPSocketConnection tcp_client;
    
    tcp_server.bind(tcp_server_port);
    tcp_server.listen();
    //uart.printf("\nWait for new connection...\n");
    tcp_server.set_blocking(false, TCP_SERVER_WAIT_CLIENT_TIMEOUT);
#endif
    
#ifdef UDP_SERVER
    UDPSocket udp_server;
    Endpoint ep_udp_client;
    
    ret = udp_server.bind(udp_server_port);
    //printf("sock.bind = %d\n", ret);
    udp_server.set_blocking(false, UDP_SERVER_RECEIVE_TIMEOUT);
#endif


    // Network processor
    while (true) {
#ifdef TCP_SERVER
        // no tcp client connected
        if (!tcp_client.is_connected())
        {
            // wait for client within timeout
            ret = tcp_server.accept(tcp_client);
            
            // tcp client connected
            if (ret > -1) {
                //uart.printf("Connection from: %s\n", tcp_client.get_address());
                
                // 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));
                    if (n <= 0) break;
                    
                    // got data, process 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;
                } // 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
        // wait for udp packet within timeout
        int n = udp_server.receiveFrom(ep_udp_client, buffer, sizeof(buffer));
        if (n < 0) continue;

        // got some data, process it
        // send to uart
        //buffer[n] = '\0';
        //message.len = n;
        //message.msg = buffer;
        //uart_queue.put(&message);
            
        // 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:
                // discovery command
                if (strstr(buffer, "NNDS") != NULL) {
                    udp_server.sendTo(ep_udp_client, ip_addr, strlen(ip_addr));
                }
                // ask for TCP server port
                else if (strstr(buffer, "NNTP") != 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) {
                    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
                }
                break;
            default:
                break;
        }
#endif
    } // network processor
}