########################################################################
an00121: Using XMOS TCP/IP Library for UDP-based Networking on XCORE-200
########################################################################

|newpage|

************
Introduction
************

*Transmission Control Protocol/Internet Protocol* (TCP/IP) is an
internetworking protocol that allows cross-platform or heterogeneous
networking. It manages the flow of data in packets with headers giving
the source and destination information. It provides a reliable stream
delivery using sequenced acknowledgment and error detection
technique. TCP/IP offers the *User Datagram Protocol* (UDP), a minimal
transport protocol, wherein the packet headers contain just enough
information to forward the datagrams and their error checking. UDP
does not support flow control and acknowledgment.


XMOS TCP/IP (XTCP)
==================

The XMOS TCP/IP component provides a IP/UDP/TCP stack that connects to
the XMOS ethernet component. It enables several clients to connect to
it and send and receive on multiple TCP or UDP connections. The stack
has been designed for a low memory embedded programming environment
and despite its low memory footprint provides a complete stack
including ARP, IPv4, UDP, TCP, DHCP, IPv4LL, ICMP and IGMP
protocols. The library provides two stacks (one based on the open-source uIP
and one based on LWIP) with modifications to work efficiently on the XMOS
architecture and communicate between tasks using xC channels. This application
note is based on the uIP stack provided in the library.

Block diagram
=============

The application firmware organization is shown in :numref:`networking_xmos_section`.

.. figure:: images/lib_xtcp_ethernet_device.png
   :alt: Networking with an XMOS device
   :scale: 75%
   :align: center
   :name: networking_xmos_section
   
   Networking with an XMOS device

|newpage|

********************************
TCP/IP Application Configuration
********************************

This section describes the configuration of the application
and the TCP/IP stack used in this example.

Project Configuration
=====================

The example uses the TCP/IP implementation in the ``lib_xtcp`` library.
It depends on ``lib_board_support`` for the PHY configuration on the
`XK_EVK_XE216` board. It depends in ``lib_logging`` for
lightweight debugging using `debug_printf()`.

These dependencies are specified in ``APP_DEPENDENT_MODULES`` in the application's `CMakeLists.txt`:

.. literalinclude:: ../../app_an00121/CMakeLists.txt
  :language: cmake
  :start-at: set(APP_DEPENDENT_MODULES
  :end-at: ")

All functions and types can be found in the ``xtcp.h`` header file:

.. code-block:: C

  #include <xtcp.h>

Allocating hardware resources
=============================

The TCP/IP stack connects to the RGMII task from the Ethernet library
which requires several ports to communicate with the
Ethernet PHY. These ports are declared in the main program file
(``main.xc``). In this demo the ports are set up for the Ethernet
PHY connected to the `XK_EVK_XE216` which uses the Gigabit Ethernet 
hardware `shim` present in the `xcore` device and is accessed using a predefined 
struct of ports defined in the type `rgmii_ports_t`:

.. literalinclude:: ../../app_an00121/src/main.xc
  :language: C
  :start-at: rgmii_ports_t
  :end-at: rgmii_ports_t

The MDIO Serial Management Interface (SMI) is used to transfer
management information between MAC and PHY. This interface consists of
two signals which are connected to two ports:

.. literalinclude:: ../../app_an00121/src/main.xc
  :language: C
  :start-at: port p_smi_mdio
  :end-at: port p_smi_mdc

.. _stack_selection_section:

Stack Selection
===============

For this example the uIP stack has be selected by default, to choose which stack
to use the options are either :c:func:`xtcp_uip` or :c:func:`xtcp_lwip` in 
``main.xc``, this is best modified by changing the option in `CMakeLists.txt`:

.. literalinclude:: ../../app_an00121/CMakeLists.txt
  :language: cmake
  :start-at: # In the compiler flags
  :end-at: set(APP_COMPILER_FLAGS

This will then switch the stack and configuration in ``main.xc`` as shown below:

.. literalinclude:: ../../app_an00121/src/main.xc
  :language: C
  :start-at: #ifdef XTCP_STACK_LWIP
  :end-at: #endif

.. _ip_configuration_section:

IP configuration
================

The IP is configured via a structure passed to the ``xtcp`` task
to suit the network where the XMOS device is used.

To assign a static IP address initialize with an address valid for the network
the device will be connected to:

.. literalinclude:: ../../app_an00121/src/main.xc
  :language: C
  :start-at: static xtcp_ipconfig_t
  :end-at: };

Alternatively it can be initialized to all zeros to enable DHCP/AutoIP, this
will attempt to dynamically assign an IP address:

.. code-block:: C

  xtcp_ipconfig_t ipconfig = {
      { 0, 0, 0, 0 }, /* ip address */
      { 0, 0, 0, 0 }, /* netmask */
      { 0, 0, 0, 0 }  /* gateway */
  };

UDP reflector
=============

The final part of the application is setup in ``udp_reflect.xc`` is a set of 
defines that assigns port numbers to the broadcast and incoming ports and also
assigns the broadcast address. The size of data buffer is also set. These 
defines are used by the application.

.. literalinclude:: ../../app_an00121/src/udp_reflect.xc
  :language: C
  :start-at: // Defines
  :end-at: BROADCAST_MSG

|newpage|

********************************
Application Detailed Description
********************************

The application main() function
===============================

For the UDP-based application example, the system comprises four tasks running
on the multicore microcontroller.

The tasks perform the following operations.

- The RGMII task ``rgmii_ethernet_mac`` which handles RGMII/Ethernet traffic.
- The RGMII config task ``rgmii_ethernet_mac_config`` which configures the RGMII task and
  handles the Ethernet PHY. This task runs on a logical core and
  communicates with the ``lib_xtcp`` stack.
- The SMI task ``smi`` which handles the Serial Management Interface (SMI) for
  the Ethernet PHY. This is used to configure the Ethernet PHY via the 
  ``ar8035_phy_driver`` task which manages the configuration of the PHY.
- The XTCP server which handles the TCP/IP stack and provides the
  interface to the application protocol. Either ``xtcp_uip`` or ``xtcp_lwip``.
- The UDP reflector application ``udp_reflect`` running in a single core.

These tasks communicate via the use of xC channels and interface
connections which allow data to  be passed between
application code running on separate logical threads.

Below is the source code for the main function of this application,
which is taken from the source file ``main.xc``

.. literalinclude:: ../../app_an00121/src/main.xc
  :language: C
  :start-at: int main

The UDP reflector function
==========================

The application code for receiving UDP packets of data from a network machine 
and reflecting it back to the same machine is implemented in the file 
``udp_reflect.xc``. Further, a fixed packet is sent periodically to a broadcast IP 
address. The code performing these tasks is contained within the function 
``udp_reflect()`` which is shown in the following pages:

.. literalinclude:: ../../app_an00121/src/udp_reflect.xc
  :language: C
  :start-at: void udp_reflect
  :end-before: while (1)

In this segment of the code you can see the following.

- The network connections, broadcast address and the buffers for holding the transmitted and received data are declared.

- The XTCP server is instructed to listen and create new connections on the incoming port.

.. literalinclude:: ../../app_an00121/src/udp_reflect.xc
  :language: C
  :start-at: while (1)
  :end-at: case XTCP_IFDOWN:
  
Other event handling follows the above code, then the repeated broadcast.

.. literalinclude:: ../../app_an00121/src/udp_reflect.xc
  :language: C
  :start-at: // This is the periodic case
  :end-at: break;

You can see the following in the rest of the code.

- The ``while`` loop waits for an XTCP event and performs the appropriate function.

- Periodical broadcast of a fixed data is done through timer events.

.. _udp_example_section:

|newpage|

***************
The UDP example
***************

Building the Application
========================

The following section assumes you have downloaded and installed the `XMOS XTC tools <https://www.xmos.com/software-tools/>`_
(see `README` for required version). Installation instructions can be found `here <https://xmos.com/xtc-install-guide>`_.
Be sure to pay attention to the section `Installation of required third-party tools
<https://www.xmos.com/documentation/XM-014363-PC-10/html/installation/install-configure/install-tools/install_prerequisites.html>`_.

The application uses the `xcommon-cmake <https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest>`_
build system as bundled with the XTC tools.

The file `CMakeLists.txt` in the `app_an00121` directory contains the application build configuration.

To configure the build run the following from an XTC command prompt, this should
only need to be run once:

.. code-block:: shell

  cd an00121
  cd app_an00121
  cmake -G "Unix Makefiles" -B build

Any missing dependencies will be downloaded by the build system as part of this configure step.

Finally, the application binaries can be built using ``xmake``:

.. code-block:: shell

  xmake -C build

This will build the application binary ``app_an00121.xe`` in the ``app_an00121/bin`` directory.

If `CMakeLists.txt` or other CMake configuration files have been modified, `xmake`
will automatically trigger cmake to regenerate the build system as required.

Demo Hardware Setup
===================

#. Connect an xTAG-3 to the `XK_EVK_XE216` XSYS port.
#. Connect the `XK_EVK_XE216` to the PC or to a network switch using an ethernet cable.
#. Connect 5V power to the `XK_EVK_XE216` using a USB cable.
#. Connect the XTAG to the host PC using a USB cable.

See :ref:`hardware_udp_setup_section`.

.. _hardware_udp_setup_section:

.. figure:: images/hardware_setup.png

	XMOS hardware setup for UDP demo

Running the example
===================

Once the application has been built you need to download the application binary
code onto the `xcore` development kit. Here you use the tools to load the application
over JTAG onto the `xcore` multicore microcontroller.

From a XTC command prompt run the following command from the `app_an00121` directory::

  xrun ./bin/app_an00121.xe

Alternatively the binary can be programmed into the non-volatile flash memory with the command::

  xflash ./bin/app_an00121.xe

When running the program with `xrun` you will see the output shown below:

.. code-block:: console

  dhcp: 192.168.200.178
  Configuration: xcore-200
  New broadcast connection established:1
  Sending broadcast message
  Sent Broadcast
  Sending broadcast message
  Sent Broadcast

Testing data transfer
=====================

The UDP example can be tested by running the python script ``test_udp.py``.

.. code-block:: console

  python test_udp.py 192.168.200.178
  Connecting..
  Connected
  Sending message: hello, world
  Revc'd message: b'HELLO, WORLD'
  Closed

This will connect to the XMOS device at the IP address specified and send a message to the UDP port 15533. 
The XMOS device will respond with the same message, with the characters translated to upper case.
The `xrun` console will display output similar to that shown below:

.. code-block:: console

  New connection to listening port: 15533
  Got data: 12 bytes
  Responding
  Sent Response
  Closed connection: 2

test_udp.py test script
-----------------------

.. literalinclude:: ../../app_an00121/src/test_udp.py
   :language: python
   :linenos:

|newpage|

***************
Further reading
***************

* XMOS XTC Tools Installation Guide

  https://xmos.com/xtc-install-guide

* XMOS XTC Tools User Guide

  https://www.xmos.com/view/Tools-15-Documentation

* XMOS application build and dependency management system; xcommon-cmake

  https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest


* XMOS TCP/IP Component

  https://www.xmos.com/libraries/lib_xtcp

* XMOS Layer 2 Ethernet MAC Component

  https://www.xmos.com/libraries/lib_ethernet
  
* XMOS logging Component

  https://www.xmos.com/libraries/lib_logging

* TCP/IP - Internet protocol suite

  https://en.wikipedia.org/wiki/Internet_protocol_suite

* IP addressing

  https://en.wikipedia.org/wiki/Internet_Protocol

* Ethernet Type

  http://en.wikipedia.org/wiki/EtherType

* UDP - User Datagram Protocol

  https://en.wikipedia.org/wiki/User_Datagram_Protocol
