AM18XX SitaraWare EMAC

Important Note:

'The software found on this site is available for download, but is no longer being actively developed and maintained. This wiki is in maintenance mode and the software is supported on Sitara E2E forum'



AM18XX Ethernet
The AM1808 uses Ethernet Media Access Controller (EMAC) and Management Data Input/Output (MDIO) module integrated in the device for implementing ethernet interface.The EMAC peripheral conforms to the IEEE 802.3 standard, describing the Carrier Sense Multiple Access with Collision Detection (CSMA/CD) Access Method and Physical Layer specifications. The EMAC module provides an efficient interface between the processor and the network. The EMAC on AM1808 supports 10Base-T (10 Mbits/sec) and 100BaseTX (100 Mbits/sec), half-duplex and full-duplex mode. The EMAC control module is the main interface between the device core processor to the EMAC and MDIO modules. The EMAC control module controls device interrupts and incorporates an 8k-byte internal RAM to hold EMAC buffer descriptors (also known as CPPI RAM). The MDIO module implements the 802.3 serial management interface to interrogate and control up to 32 Ethernet PHYs connected to the device by using a shared two-wire bus. The application shall use the MDIO module to configure the auto negotiation parameters of each PHY attached to the EMAC, retrieve the negotiation results, and configure required parameters in the EMAC module for correct operation. The APIs for configuring and using EMAC and MDIO are exported in /include/emac.h and /include/mdio.h respectively.

Lan8710a
LAN8710A is a low-power 10BASE-T/100BASE-TX physical layer (PHY) transceiver which communicates with the EMAC via standard MII/RMII Interface. All the configuration and register settings of the PHY will be done via MDIO interface. The APIs for configuring LAN8710A are exported in /include/lan8710a.h.

Design overview
The SitaraWare Ethernet software deliverable can be broadly classified into three main components:
 * 1) The device abstraction layer - EMAC DAL, MDIO DAL, PHY DAL
 * 2) The LWIP Network Interface Layer - Sitara NetIF port for LWIP
 * 3) The LWIP based application layer - An IP stack based application based on LWIP. For example HTTP server, UDP based client, an embedded web server serving control pages etc. The packets start and end at this layer.
 * 4) The System application layer - The application layer which is used for AM1808 initialization and can be used for any other algorithm of the system



The device level abstraction layer
This layer implements the lowest level hardware abstraction APIs which can be used for control and configuration of the EMAC device. There are three files that form this layer and are located at SitaraWare_xx_yy_mm_pp/drivers/


 * emac.c which acts upon the Ethernet MAC and Control module
 * mdio.c which acts upon the MDIO interface between the PHY and MAC
 * lan8710a.c which acts upon the PHY device.

The device abstraction layer is implemented as a very light layer just for hardware/device access and conforms to the generic framework of SitaraWare - it does not maintain any state variables.

The lwIP interface layer
For realistic interfacing of Ethernet device with the rest of the network, the device abstraction layer needs to be glued with a network stack that can form/interpret network packets. The choice is to have lwIP, for its no OS adaptability and support for fair number of network protocols. The device abstraction is glued by implementing the interface layer of lwIP. This is also called as the sitara-port for the lwIP or the sitara-interface for lwIP. This lwIP interface layer forms a major part of the SitaraWare network driver. It defines standard interface entry points and interface state variable. A network device is represented by "struct netif", generically referred to as netif. The netif contains all the information about the interface, like the IP/MAC address(s), TCP/IP options, protocol handlers, link Information and most importantly the network device driver entry point callbacks. Every network interface, as also sitara interface, implements the linkoutput and init callbacks. Also, any state information is maintained in this structure. The interface layer also implement the core interrupt handling and DMA handling. All the required function calls for initializing the lwIP stack and registering the sitara network interface are abstracted under the lwiplib.c. Refer to lwip.pdf for details on lwIP stack implementation. Further sections below explain the network interface initialization and registration. This is located at third_party/lwip-1.3.2/ports/am1808/

Sitara network interface layer
The main tasks of the Sitara network interface layer are


 * Network device initialization

Network device initialization, which is the first step towards bringing up the interface, is done as part of the sitaraif_init. This function is called when the network device is being registered with the lwip stack using netif_add. As part of the initialization, the netif output callbacks are registered and h/w initialization, which includes PHY and DMA initialization, are completed. DMA buffer descriptor(bd) pools are maintained in the CPPI RAM for both TX and RX channels. The descriptor chains are maintained by the "free_head" which points to the next unused/free descriptor in the bd pool, "active_tail" which points to the last bd in the active queue which has been en-queued to the hardware. The packet buffers (pbuf) are pre-allocated for maximum length and queued in the receive buffer descriptors before the reception begins. Please refer to lwip.pdf Section 6, for details on pbuf handling by lwIP.


 * Packet data transmission

The packet data transmission takes place in the context of linkoutput callback registered with the lwIP stack. This callback is invoked whenever the lwIP stack receives a packet for transmission from the application layer. The pbuf can contain a chain of packet buffers and hence the DMA descriptors are properly updated (chained if necessary), with SOP, EOP and length fields. The first DMA descriptor is marked with the EOP and OWNER flags, while only the last is set with the EOP flag. After filling the bd's with the pbuf information, the bd, which corresponds to the SOP is written to the HEAD descriptor pointer register to start the transmission. Once a packet is transmitted, the EMAC Control Core will generate a transmit interrupt. This interrupt will be cleared only if the completion pointer is written with the last bd processed. In the interrupt handler, the next bd to process is taken then traversed to reach the bd which corresponds to the end of the packet. This bd, which corresponds to the end of the packet is written to the completion pointer. After this, the pbuf which corresponds to this packet is freed. Thus it is made sure that the freeing of pbuf is done only after the packet transmission is complete.


 * Packet data reception

The packet reception takes place in the context of the interrupt handler for receive. As described earlier, the receive buffer descriptors are en-queued to the DMA before the reception can actually begin. The pbuf allocated for maximum length, may actually contain a chain of packet buffers. The descriptors are updated for OWNER flag only. The EOP, SOP and EOQ are updated by the DMA upon completion of the reception. One important point to note is that, the actual data received may be less/more than the max length allocated. Hence the pbuf chain needs to be adjusted as detailed here. First, the active_head (which is the first bd en-queued), is checked for OWNER bit having been cleared by the DMA. Then the bd list is traversed, starting at the active_head, to find the EOP bd, which is the last bd of the current packet. While doing so if the EOP is not found on the current bd, then the pbuf of the current bd is chained to the pbuf of the next bd, since the current packet has spilled over to the next bd. Once, the EOP is found the last pbuf is updated as the terminator (pbuf-&gt;next = NULL). Thus, the entire packet is collected and passed to the upper layer for processing. Since, the current bd has been done with, it is put back at the free_head, by allocating a new pbuf.

The lwIP application layer
This layer contains the ethernet application like a HTTP server, an echo server etc. This is located at "SitaraWare_xx_yy_mm_pp/third_party/lwip-1.3.2/apps/ /". This is the layer at which all the imcoming packets terminate and all outgoing packets originate.

The System application layer
This layer implements system level initialization and provides options for lwIP stack. This layer can contain any other algorithms, decoding etc. The main IP stack based application is part of the lwip directory as mentioned above.

EMAC Programming
When the device is powered on EMAC will be in a disabled state. Proper pin multiplexing has to be done for EMAC and MDIO modules. Also, before any EMAC specific initialization, the EMAC and MDIO modules shall be enabled in PSC registers. The below sequence can be used configure and use the EMAC and MDIO modules.


 * Enable the pin multiplexing for EMAC and MDIO using EMACPinMuxSetup API.
 * Enable the EMAC and MDIO modules in PSC registers using the API PSCModuleControl.
 * Initialize the EMAC module by invoking EMACInit. This API resets the EMAC and EMAC Control Module Registers.
 * Initialize the MDIO Module usingMDIOInit. Enough delay shall be given to ensure the successful completion of the MDIO module initialization before any further access to MDIO.
 * Auto negotiate with the PHY device connected through the MDIO. Respective PHY Auto negotiation API can be used for this.
 * On successful completion of auto negotiation, get the auto negotiation result using the respective PHY’s link partner ability API and set the duplex mode of operation in the EMAC using EMACDuplexSet.
 * Set the MAC Address in the EMAC hardware using EMACMACAddrSet.
 * Enable unicast for a specific channel using the API EMACRxUnicastSet, if desired.
 * Initialize the TX and RX buffer descriptors in the CPPI RAM, which is local to the EMAC.
 * Enable the TX operation in EMAC using EMACTxEnable. This enables the EMAC hardware transmit operation. However, transmission will start only if a valid descriptor pointer is written using EMACTxHdrDescPtrWrite.
 * Enable the RX operation in EMAC using EMACRXEnable
 * Write the RX Header Descriptor Pointer using EMACRxHdrDescPtrWrite. The EMAC hardware will start receiving data at this point. The data will be stored to the buffer pointer in this buffer descriptor. After the buffer corresponding to this descriptor is filled, the next descriptor is used by the EMAC hardware according to the buffer descriptor settings.
 * Enable MII using EMACMIIEnable
 * Enable the Transmit and Receive Pulse interrupts using EMACTxIntPulseEnable and EMACRxIntPulseEnable. The interrupts will be routed through the EMAC Control Core to the ARM Interrupt Controller. This enables the EMAC TX and RX pulse interrupts at EMAC peripheral level only. The core interrupts shall be enabled separately in the interrupt controller.


 * In an EMAC Transmit interrupt handler, the interrupt shall be acknowledged to the EMAC hardware using EMACCoreIntAck. However, the interrupt will be cleared only if the completion pointer is written using the API EMACTxCPWrite with the last processed TX buffer descriptor.
 * In an EMAC Receive interrupt handler, the interrupt shall be acknowledged to the EMAC hardware using EMACCoreIntAck. Again, the interrupt will be cleared only if the completion pointer is written using the API EMACRxCPWrite with the last processed RX buffer descriptor.

Example applications
'''TMS470 Tool chain does not support packed attributes. This leads to issues when ethernet applications, built with TMS470 tool chain, are executed on the target. Hence, please do not use/connect ethernet in the demo. This issue is documented in the Known issues section of the release notes'''

The SitaraWare AM18XX ethernet application over lwIP stack is demonstrated using two applications.
 * 1) An embedded web server application, which hosts a default page when requested
 * 2) An echo server application, which demonstrates a simple data transfer between a client and server.


 * Modules used in this example
 * EMAC
 * MDIO
 * LAN8710A
 * Interrupt
 * UART
 * lwIP Stack

In the following examples, the MAC Address and IP address can be configured in enet_lwip/include/lwipopts.h. The macro MAC_ADDRESS shall specify the MAC address and STATIC_IP_ADDRESS shall specify the static IP address to be used. If a dynamic IP address to be used, STATIC_IP_ADDRESS shall be defined as 0.

Embedded Web Server application
A sample http server application is demonstrated, using lwIP stack. This is located at SitaraWare_xx_yy_mm_pp/examples/evmAM1808/enet_lwip/.

Before executing the example, ensure that the serial port on board is connected to the host machine and a serial terminal application (like TeraTem/Hyperterminal/minicom) is running on the host. The example uses a serial console to display the dynamic IP address assigned for the EVM by the DHCP server. Flash the Ethernet example application or load the executable ELF (.out) file on to the EVM.


 * Testing by connecting peer to peer with a host machine:
 * Connect the Ethernet port on board to the host Ethernet port via an Ethernet cable
 * Assign a static IP address to the host machine.
 * Run a DHCP server application on the host.
 * Execute the example application
 * Note the dynamic IP address assigned which displayed on the serial console.
 * Access the http server application default page using  via a web browser on the host.
 * Ensure that proxy server is not used for the dynamic IP address assigned for the board.


 * Testing by connecting to a corporate network:
 * Connect the Ethernet port on board to a port on the corporate network.
 * Execute the example application.
 * Note the dynamic IP address assigned which displayed on the serial console.
 * Access the http server application default page using  via a web browser on the host.
 * Ensure that proxy server is not used for the dynamic IP address assigned for the board.

Echo server application
A sample echo server-client set up is demonstrated, using lwIP stack. The echo server, which runs on the target just echos back the received data to the sender - typically the client running on a Linux host in this case. The client then compares the sent and received data for integrity and the result is printed on the client console. The client application is also delivered as part of package and is located at SitaraWare_xx_yy_mm_pp/host_apps/enet_client.

Before executing the example, ensure that the serial port on board is connected to the host machine and a serial terminal application (like TeraTem/Hyperterminal/minicom) is running on the host. The example uses a serial console to display the dynamic IP address assigned for the EVM by the DHCP server. Flash the Ethernet example application or load the executable ELF (.out) file on to the EVM.


 * Testing by connecting peer to peer with a host machine:
 * Connect the Ethernet port on board to the host Ethernet port via an Ethernet cable
 * Assign a static IP address to the host machine.
 * Run a DHCP server application on the host.
 * Execute the example application on the target


 * Testing by connecting to a corporate network:
 * Connect the Ethernet port on board to a port on the corporate network.
 * Execute the example application on the target.
 * Note the dynamic IP address assigned which displayed on the serial console.

Now execute the client application on the host.

$ ./client 

The client prints the status of the application on the console

makefsfile utility
'makefsfile' may be used to create file system images to embed in ethernet applications offering web server interfaces. It can be used to generate an ASCII C file containing initialized data structures, which represents the html pages which need to be embedded in the application. 'makefsfile' is at "tools/makefsfile/", provided in source and binary form. Executing the binary without any input provides a detailed help menu which guides the user.

Executing makefsfile utility
$ ./makefsfile This prints a detailed help menu

$./makefsfile -i  &lt;directory-path&gt; This takes an input directory path which contains the saved html pages which need to be converted to a C file which can be embedded in an application. The file fsdata.c will be generated inside directory from where makefsfile is executed.