A4MCAR - Ethernet (TCP Server) task implementation added along with phy drivers, port and configuration files.

Signed-off-by: Mustafa Ozcelikors <mozcelikors@gmail.com>
diff --git a/a4mcar/low_level_applications/src/ar8035_phy_driver.h b/a4mcar/low_level_applications/src/ar8035_phy_driver.h
new file mode 100644
index 0000000..0a15702
--- /dev/null
+++ b/a4mcar/low_level_applications/src/ar8035_phy_driver.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - AR8035 PHY driving task for Ethernet communication implementation - Header file
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Contributors:
+ *    This code uses the following repository as skeleton:
+ *    https://github.com/Pajeh/XMOS_gigabit_tcp_reflect
+ *
+ * Update History:
+ *
+ */
+
+#ifndef AR8035_PHY_DRIVER_H_
+#define AR8035_PHY_DRIVER_H_
+
+#include "defines.h"
+
+[[combinable]]
+ void Task_Ar8035_Phy_Driver (port p_eth_reset, client interface smi_if smi, client interface ethernet_cfg_if eth);
+
+#endif /* AR8035_PHY_DRIVER_H_ */
diff --git a/a4mcar/low_level_applications/src/ar8035_phy_driver.xc b/a4mcar/low_level_applications/src/ar8035_phy_driver.xc
new file mode 100644
index 0000000..81094de
--- /dev/null
+++ b/a4mcar/low_level_applications/src/ar8035_phy_driver.xc
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - AR8035 PHY driving task for Ethernet communication implementation
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Contributors:
+ *    This code uses the following repository as skeleton:
+ *    https://github.com/Pajeh/XMOS_gigabit_tcp_reflect
+ *
+ * Update History:
+ *
+ */
+
+#include "ar8035_phy_driver.h"
+#include "core_debug.h"
+
+/***
+ *  Function Name:                Task_Ar8035_Phy_Driver
+ *  Function Description :        Task that is responsible for driving AR8035 chip in order to maintain Ethernet communication
+ *
+ *  Argument                Type                                Description
+ *  p_eth_reset             port                                Ethernet reset port
+ *  smi                     client interface smi_if             SMI client interface
+ *  eth                     client interface ethernet_cfg_if    Ethernet config interface
+ */
+[[combinable]]
+void Task_Ar8035_Phy_Driver (port p_eth_reset, client interface smi_if smi, client interface ethernet_cfg_if eth)
+{
+    PrintCoreAndTileInformation("ar8035_phy_driver");
+    ethernet_link_state_t link_state = ETHERNET_LINK_DOWN;
+    //For RGMII version:
+    //ethernet_speed_t link_speed = LINK_1000_MBPS_FULL_DUPLEX;
+    //For Non-RGMII version:
+    ethernet_speed_t link_speed = LINK_100_MBPS_FULL_DUPLEX;
+    const int phy_reset_delay_ms = 1;
+    const int link_poll_period_ms = 1000;
+    const int phy_address = 0x4;
+    timer tmr;
+    int t;
+    tmr :> t;
+    p_eth_reset <: 0;
+    delay_milliseconds(phy_reset_delay_ms);
+    p_eth_reset <: 1;
+
+    while (smi_phy_is_powered_down(smi, phy_address));
+    //For RGMII version:
+    //smi_configure(smi, phy_address, LINK_1000_MBPS_FULL_DUPLEX, SMI_ENABLE_AUTONEG);
+
+    //For Non-RGMII version:
+    smi_configure(smi, phy_address, LINK_100_MBPS_FULL_DUPLEX, SMI_DISABLE_AUTONEG);
+
+    while (1) {
+        select {
+        case tmr when timerafter(t) :> t:
+            ethernet_link_state_t new_state = smi_get_link_state(smi, phy_address);
+
+            // Read AR8035 status register bits 15:14 to get the current link speed
+            if (new_state == ETHERNET_LINK_UP) {
+                link_speed = (ethernet_speed_t)(smi.read_reg(phy_address, 0x11) >> 14) & 3;
+            }
+            if (new_state != link_state) {
+                link_state = new_state;
+                eth.set_link_state(0, new_state, link_speed);
+            }
+            t += link_poll_period_ms * XS1_TIMER_KHZ;
+            break;
+        }
+    }
+}
+
diff --git a/a4mcar/low_level_applications/src/ethernet_app.h b/a4mcar/low_level_applications/src/ethernet_app.h
new file mode 100644
index 0000000..228a9bf
--- /dev/null
+++ b/a4mcar/low_level_applications/src/ethernet_app.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - TCP Server implementation and TCP Server task in Low Level Module using XMOS xCORE-200 eXplorerKIT - Header file
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Contributors:
+ *    This code uses the following repository as skeleton:
+ *    https://github.com/Pajeh/XMOS_gigabit_tcp_reflect
+ *
+ * Update History:
+ *
+ */
+
+#ifndef ETHERNET_APP_H_
+#define ETHERNET_APP_H_
+
+#include "defines.h"
+
+// Defines
+#define RX_BUFFER_SIZE 1400
+#define INCOMING_PORT 15534
+#define INIT_VAL -1
+#define YOUSEND "You sent: "
+#define ETHERNET_SMI_PHY_ADDRESS (0)
+#define ETHERNET_TO_RN42_INTERFACE_COMMANDLENGTH 8
+
+enum flag_status {TRUE=1, FALSE=0};
+
+// Prototypes
+void Task_EthernetAppTCPServer (chanend c_xtcp, client ethernet_to_cmdparser_if cmd_from_ethernet_to_override, server core_stats_if core_stats_interface_tile0,
+                                                                                                               server core_stats_if core_stats_interface_tile1);
+#endif /* ETHERNET_APP_H_ */
diff --git a/a4mcar/low_level_applications/src/ethernet_app.xc b/a4mcar/low_level_applications/src/ethernet_app.xc
new file mode 100644
index 0000000..280deca
--- /dev/null
+++ b/a4mcar/low_level_applications/src/ethernet_app.xc
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - TCP Server implementation and TCP Server task in Low Level Module using XMOS xCORE-200 eXplorerKIT
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Contributors:
+ *    This code uses the following repository as skeleton:
+ *    https://github.com/Pajeh/XMOS_gigabit_tcp_reflect
+ *
+ * Update History:
+ *
+ */
+
+#include "ethernet_app.h"
+#include <xtcp.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "string_itoa.h"
+#include "core_debug.h"
+
+/***
+ *  Function Name:                Task_EthernetAppTCPServer
+ *  Function Description :        This task implements a TCP server to handle a two-way communication between low level module and high level module.
+ *                                High-level sends ----> a driving command to override driving behavior.
+ *                                Low-level sends  ----> core usage information of Low-Level module that are retrieved by using core_stats_interface_tile0
+ *                                                       and core_stats_interface_tile1
+ *
+ *  Argument                        Type                            Description
+ *  c_xtcp                          chanend                         Channel end to communicate with the xtcp task which is responsible for implementing the TCP protocol communication
+ *  cmd_from_ethernet_to_override   client ethernet_to_cmdparser_if Driving command that is to be sent through Ethernet Server is received using this interface.
+ *  core_stats_interface_tile0      server core_stats_if            A server interface that is used for receiving core usage information (for Tile 0) from the task that is responsible for core monitoring.
+ *  core_stats_interface_tile1      server core_stats_if            A server interface that is used for receiving core usage information (for Tile 1) from the task that is responsible for core monitoring.
+ */
+void Task_EthernetAppTCPServer(chanend c_xtcp, client ethernet_to_cmdparser_if cmd_from_ethernet_to_override, server core_stats_if core_stats_interface_tile0,
+                                                                                                              server core_stats_if core_stats_interface_tile1)
+{
+      xtcp_connection_t conn;     // A temporary variable to hold connections associated with an event
+      xtcp_connection_t responding_connection;    // The connection to the remote end we are responding to
+      int send_flag = FALSE;  // This flag is set when the thread is in the middle of sending a response packet
+
+      // The buffers for incoming data, outgoing responses and outgoing broadcast messages
+      char rx_buffer[RX_BUFFER_SIZE];
+      char tx_buffer[RX_BUFFER_SIZE];
+
+      int response_len;   // The length of the response the thread is sending
+
+      // Maintain track of two connections. Initially they are not initialized
+      // which can be represented by setting their ID to -1
+      responding_connection.id = INIT_VAL;
+
+      // Instruct server to listen and create new connections on the incoming port
+      xtcp_listen(c_xtcp, INCOMING_PORT, XTCP_PROTOCOL_TCP);
+
+      //Core usage info
+      short int core_usage_tile0[8], core_usage_tile1[8];
+      int connected = 0; //Connection flag
+
+      //Timer to delay send operation
+      timer tmr;
+      unsigned int time, delay = 5000 * MILLISECOND;
+      tmr :> time;
+
+      int string_ptr = 0;
+      int string_ptr2 = 0;
+
+      char str_buffer[4];
+
+      PrintCoreAndTileInformation("Task_EthernetAppTCPServer");
+
+      while (1)
+      {
+          select
+          {
+          case tmr when timerafter(time) :> void : // Timer event
+                  if (!send_flag && connected==1)
+                  {
+                        //When client is connected and timer is ready, construct the tx_buffer
+                        string_ptr = 0;
+
+                        for ( int k = 0; k <= 7; k++)
+                        {
+                            string_ptr2 = 0;
+                            itoa (core_usage_tile0[k], str_buffer, 4, 10);
+                            //printf("%s ",str_buffer);
+
+                            while (str_buffer[string_ptr2] != '\0')
+                            {
+                                tx_buffer[string_ptr] = str_buffer[string_ptr2];
+                                string_ptr += 1;
+                                string_ptr2 += 1;
+                            }
+                            if (k!=7)
+                            {
+                                tx_buffer[string_ptr] = ',';
+                                string_ptr += 1;
+                            }
+                        }
+
+                        tx_buffer[string_ptr] = ',';
+                        string_ptr += 1;
+
+                        for ( int k = 0; k <= 7; k++)
+                        {
+                            string_ptr2 = 0;
+                            itoa (core_usage_tile1[k], str_buffer, 4, 10);
+                            //printf("%s ",str_buffer);
+
+                            while (str_buffer[string_ptr2] != '\0')
+                            {
+                                tx_buffer[string_ptr] = str_buffer[string_ptr2];
+                                string_ptr += 1;
+                                string_ptr2 += 1;
+                            }
+                            if (k!=7)
+                            {
+                                tx_buffer[string_ptr] = ',';
+                                string_ptr += 1;
+                            }
+                        }
+
+                        tx_buffer[string_ptr] = 'E';
+                        string_ptr += 1;
+
+                        //printf("%s \n",tx_buffer);
+                        response_len = string_ptr;
+
+                        //Once tx_buffer is ready, initialize TCP sending
+                        xtcp_init_send(c_xtcp, conn);
+                        send_flag = TRUE;
+
+                  }
+                  time += delay;
+                  //printf("h\n");
+                  break;
+
+          case core_stats_interface_tile0.ShareCoreUsage (unsigned int core0, unsigned int core1, unsigned int core2, unsigned int core3, unsigned int core4, unsigned int core5, unsigned int core6, unsigned int core7):
+                  //Event to receive core utilization information from core monitoring task when ready (for Tile 0)
+                  core_usage_tile0[0]=core0;
+                  core_usage_tile0[1]=core1;
+                  core_usage_tile0[2]=core2;
+                  core_usage_tile0[3]=core3;
+                  core_usage_tile0[4]=core4;
+                  core_usage_tile0[5]=core5;
+                  core_usage_tile0[6]=core6;
+                  core_usage_tile0[7]=core7;
+                  break;
+
+          case core_stats_interface_tile1.ShareCoreUsage (unsigned int core0, unsigned int core1, unsigned int core2, unsigned int core3, unsigned int core4, unsigned int core5, unsigned int core6, unsigned int core7):
+                  //Event to receive core utilization information from core monitoring task when ready (for Tile 1)
+                  core_usage_tile1[0]=core0;
+                  core_usage_tile1[1]=core1;
+                  core_usage_tile1[2]=core2;
+                  core_usage_tile1[3]=core3;
+                  core_usage_tile1[4]=core4;
+                  core_usage_tile1[5]=core5;
+                  core_usage_tile1[6]=core6;
+                  core_usage_tile1[7]=core7;
+                  break;
+
+          // Respond to an event from the TCP server
+          case xtcp_event(c_xtcp, conn):
+              switch (conn.event)
+              {
+                  case XTCP_IFUP:
+                  case XTCP_IFDOWN:
+                      break;
+
+                  case XTCP_NEW_CONNECTION:
+                      // The tcp server is giving us a new connection.
+                      // This is a new connection to the listening port
+          #ifdef DEBUG
+                      printstr("New connection to listening port:");
+                      printintln(conn.local_port);
+          #endif
+                      printstr("New connection to listening port:");
+                      printintln(conn.local_port);
+
+                      //Connected flag:
+                      connected = 1;
+                      time += 2000 * MILLISECOND; //Delay sending a bit
+
+                      if (responding_connection.id == INIT_VAL)
+                      {
+                          responding_connection = conn;
+                      }
+                      else
+                      {printstr("Cannot handle new connection");
+          #ifdef DEBUG
+                          printstr("Cannot handle new connection");
+          #endif
+                          xtcp_close(c_xtcp, conn);
+                      }
+                      break;
+
+                  case XTCP_RECV_DATA:
+                      // When we get a packet in:
+                      //
+                      //  - fill the tx buffer
+                      //  - initiate a send on that connection
+                      //
+
+                      response_len = xtcp_recv_count(c_xtcp, rx_buffer, RX_BUFFER_SIZE);
+                      rx_buffer[response_len] = 0;
+          #ifdef DEBUG
+                      printstr("Got data: ");
+                      printint(response_len);
+                      printstrln(" bytes");
+          #endif
+
+                      //Send data to bluetooth command parser to override the command -optional
+                      //printstrln(rx_buffer);
+                      cmd_from_ethernet_to_override.SendCmd(rx_buffer, ETHERNET_TO_RN42_INTERFACE_COMMANDLENGTH);
+
+          #ifdef DEBUG
+                          printstr("Responding: ");
+                          printstrln(rx_buffer);}
+          #endif
+
+
+                         break;
+
+                  case XTCP_REQUEST_DATA:
+                  case XTCP_RESEND_DATA:
+                  case XTCP_SENT_DATA:
+                              // The tcp server wants data for the reponding connection
+                              if (send_flag == TRUE)
+                              {
+                  #ifdef DEBUG
+                                  printstr("Resending data pf length ");
+                                  printintln(response_len);
+                  #endif
+                                  xtcp_send(c_xtcp, tx_buffer, response_len);
+                              }
+                              else
+                              {
+                                  xtcp_complete_send(c_xtcp);
+                              }
+
+                              break;
+                  case XTCP_TIMED_OUT:
+                  case XTCP_ABORTED:
+                  case XTCP_CLOSED:
+          #ifdef DEBUG
+                      printstr("Closed connection:");
+                      printintln(conn.id);
+          #endif
+                      xtcp_close(c_xtcp, conn);
+                      responding_connection.id = INIT_VAL;
+                      send_flag = FALSE;
+                      connected = 0;
+                      break;
+
+                  case XTCP_ALREADY_HANDLED:
+                      break;
+              }
+          break;
+      }
+  }
+}
diff --git a/a4mcar/low_level_applications/src/ethernet_config.h b/a4mcar/low_level_applications/src/ethernet_config.h
new file mode 100644
index 0000000..5837f18
--- /dev/null
+++ b/a4mcar/low_level_applications/src/ethernet_config.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - This file includes Ethernet IP configuration and OTP memory access port
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Contributors:
+ *    This code uses the following repository as skeleton:
+ *    https://github.com/Pajeh/XMOS_gigabit_tcp_reflect
+ *
+ * Update History:
+ *
+ */
+
+#ifndef ETHERNET_CONFIG_H_
+#define ETHERNET_CONFIG_H_
+
+#include "defines.h"
+
+// Defines
+#define DEBUG 1
+#define ETHERNET_SMI_PHY_ADDRESS (0)
+#define DATAINTERFACES  5
+
+// An enum to manage the array of connections from the ethernet component
+// to its clients.
+enum eth_clients {
+  ETH_TO_ICMP,
+  NUM_ETH_CLIENTS
+};
+
+enum cfg_clients {
+  CFG_TO_ICMP,
+  CFG_TO_PHY_DRIVER,
+  NUM_CFG_CLIENTS
+};
+
+// IP Configuration of the Ethernet device
+// To set a dynamic IP:
+xtcp_ipconfig_t ipconfig = {
+        {192,168,20,60}, // ip address (eg 192,168,0,2)
+        {255,255,255,0}, // netmask (eg 255,255,255,0)
+        {192,168,20,1}   // gateway (eg 192,168,0,1)
+};
+
+// To set a static IP, leave everything as 0:
+//xtcp_ipconfig_t ipconfig = {
+//        { 0, 0, 0, 0 }, // ip address (eg 192,168,0,2)
+//        { 0, 0, 0, 0 }, // netmask (eg 255,255,255,0)
+//        { 0, 0, 0, 0 }  // gateway (eg 192,168,0,1)
+//};
+
+
+#endif /* ETHERNET_CONFIG_H_ */
diff --git a/a4mcar/low_level_applications/src/port_definitions.h b/a4mcar/low_level_applications/src/port_definitions.h
new file mode 100644
index 0000000..efaca7c
--- /dev/null
+++ b/a4mcar/low_level_applications/src/port_definitions.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 FH Dortmund.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    A4MCAR Project - Low-level Module Port, Clock and File Definitions for XMOS xCORE-200 eXplorerKIT
+ *
+ * Authors:
+ *    M. Ozcelikors <mozcelikors@gmail.com>
+ *
+ * Update History:
+ *
+ */
+
+#ifndef PORT_DEFINITIONS_H_
+#define PORT_DEFINITIONS_H_
+
+#include "defines.h"
+
+// UART Ports
+    on tile[0] : port PortUART_TX = XS1_PORT_1N;
+    on tile[0] : port PortUART_RX = XS1_PORT_1M;
+
+// Steering Servo Related Defines
+    on tile[0] : out port PortSteeringServo = XS1_PORT_1L; //J10
+
+// Motor Speed Controller Defines
+    on tile[0] : port PortMotorSpeedController = XS1_PORT_1G; //J8
+
+// Relay Module Port for Braking
+    on tile[0] : port PortBRAKEctrl = XS1_PORT_1O; //GPIO J1 connector (Tile0), Signal X0D38
+
+// I2C Related Ports
+    on tile[0] : port PortSCL = XS1_PORT_1E; //D12
+    on tile[0] : port PortSDA = XS1_PORT_1F; //D13
+
+// Light system PWM ports
+    on tile[0] : port PortLightSystem_TH = XS1_PORT_1K;  //J12  P1K
+    on tile[0] : port PortLightSystem_ST = XS1_PORT_1H;  //J13  P1H
+
+// Ethernet related Ports & clocks
+    // These ports are for accessing the OTP memory
+    otp_ports_t otp_ports = on tile[0]: OTP_PORTS_INITIALIZER;
+
+    rgmii_ports_t rgmii_ports = on tile[1]: RGMII_PORTS_INITIALIZER;
+
+    port p_smi_mdio   = on tile[1]: XS1_PORT_1C;
+    port p_smi_mdc    = on tile[1]: XS1_PORT_1D;
+    port p_eth_reset  = on tile[1]: XS1_PORT_1N;
+
+    port leds = on tile[0]: XS1_PORT_4F;
+
+    clock clk = on tile[0]: XS1_CLKBLK_1;
+
+
+
+#endif /* PORT_DEFINITIONS_H_ */