Robobo
Quickstart guide for EMAC driver.

This is the quickstart guide for the Ethernet MAC, with step-by-step instructions on how to configure and use the driver in a selection of use cases.

The use cases contain several code fragments. The code fragments in the steps for setup can be copied into a custom initialization function, while the steps for usage can be copied into, e.g., the main application function.

Basic use case

In the basic use case, the EMAC driver are configured for:

  • PHY component DM9161A is used
  • EMAC uses RMII mode
  • The number of receive buffer is 16
  • The number of transfer buffer is 8
  • MAC address is set to 00-04-25-1c-a0-02
  • IP address is set to 192.168.0.2
  • IP address is set to 192.168.0.2
  • Gateway is set to 192.168.0.1
  • Network mask is 255.255.255.0
  • PHY operation max retry count is 1000000
  • EMAC is configured to not support copy all frame and support broadcast
  • The reset PIN of DM9161A is connected to the NRST of SAM3X
  • The data will be read from the ethernet

Setup steps

Prerequisites

  1. System Clock Management (sysclock)
  2. Parallel Input/Output Controller (pio)
  3. Power Management Controller (pmc)
  4. Reset Controller (RSTC)
  5. PHY component (DM9161A)

Example code

Content of conf_eth.h

#define EMAC_RX_BUFFERS 16
#define EMAC_TX_BUFFERS 8
#define MAC_PHY_RETRY_MAX 1000000
#define ETHERNET_CONF_ETHADDR0 0x00
#define ETHERNET_CONF_ETHADDR0 0x00
#define ETHERNET_CONF_ETHADDR1 0x04
#define ETHERNET_CONF_ETHADDR2 0x25
#define ETHERNET_CONF_ETHADDR3 0x1C
#define ETHERNET_CONF_ETHADDR4 0xA0
#define ETHERNET_CONF_ETHADDR5 0x02
#define ETHERNET_CONF_IPADDR0 192
#define ETHERNET_CONF_IPADDR1 168
#define ETHERNET_CONF_IPADDR2 0
#define ETHERNET_CONF_IPADDR3 2
#define ETHERNET_CONF_GATEWAY_ADDR0 192
#define ETHERNET_CONF_GATEWAY_ADDR1 168
#define ETHERNET_CONF_GATEWAY_ADDR2 0
#define ETHERNET_CONF_GATEWAY_ADDR3 1
#define ETHERNET_CONF_NET_MASK0 255
#define ETHERNET_CONF_NET_MASK1 255
#define ETHERNET_CONF_NET_MASK2 255
#define ETHERNET_CONF_NET_MASK3 0
#define ETH_PHY_MODE BOARD_EMAC_MODE_RMII

A specific emac device and the receive data buffer must be defined; another ul_frm_size should be defined to trace the actual size of the data received.

static emac_device_t gs_emac_dev;
static volatile uint8_t gs_uc_eth_buffer[EMAC_FRAME_LENTGH_MAX];
uint32_t ul_frm_size;

Add to application C-file:

void emac_init(void)
{
sysclk_init();
board_init();
};
ul_delay = sysclk_get_cpu_hz() / 1000 / 3 * 400;
while (ul_delay--);
emac_option.uc_copy_all_frame = 0;
emac_option.uc_no_boardcast = 0;
memcpy(emac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
gs_emac_dev.p_hw = EMAC;
emac_dev_init(EMAC, &gs_emac_dev, &emac_option);
NVIC_EnableIRQ(EMAC_IRQn);
ethernet_phy_init(EMAC, BOARD_EMAC_PHY_ADDR, sysclk_get_cpu_hz()
ethernet_phy_auto_negotiate(EMAC, BOARD_EMAC_PHY_ADDR
ethernet_phy_set_link(EMAC, BOARD_EMAC_PHY_ADDR, 1)

Workflow

  1. Ensure that conf_emac.h is present and contains the following configuration symbol. This configuration file is used by the driver and should not be included by the user.
    • #define EMAC_RX_BUFFERS 16
      #define EMAC_TX_BUFFERS 8
      #define MAC_PHY_RETRY_MAX 1000000
      #define ETHERNET_CONF_ETHADDR0 0x00
      #define ETHERNET_CONF_ETHADDR0 0x00
      #define ETHERNET_CONF_ETHADDR1 0x04
      #define ETHERNET_CONF_ETHADDR2 0x25
      #define ETHERNET_CONF_ETHADDR3 0x1C
      #define ETHERNET_CONF_ETHADDR4 0xA0
      #define ETHERNET_CONF_ETHADDR5 0x02
      #define ETHERNET_CONF_IPADDR0 192
      #define ETHERNET_CONF_IPADDR1 168
      #define ETHERNET_CONF_IPADDR2 0
      #define ETHERNET_CONF_IPADDR3 2
      #define ETHERNET_CONF_GATEWAY_ADDR0 192
      #define ETHERNET_CONF_GATEWAY_ADDR1 168
      #define ETHERNET_CONF_GATEWAY_ADDR2 0
      #define ETHERNET_CONF_GATEWAY_ADDR3 1
      #define ETHERNET_CONF_NET_MASK0 255
      #define ETHERNET_CONF_NET_MASK1 255
      #define ETHERNET_CONF_NET_MASK2 255
      #define ETHERNET_CONF_NET_MASK3 0
      #define ETH_PHY_MODE BOARD_EMAC_MODE_RMII
  2. Enable the system clock:
    • sysclk_init();
  3. Enable PIO configurations for EMAC:
    • board_init();
  4. Reset PHY; this is required by the DM9161A component:
  5. Wait for PHY ready:
    • ul_delay = sysclk_get_cpu_hz() / 1000 / 3 * 400;
      while (ul_delay--);
  6. Enable PMC clock for EMAC:
  7. Set the EMAC options; it's set to copy all frame and support broadcast:
    • emac_option.uc_copy_all_frame = 0;
      emac_option.uc_no_boardcast = 0;
      memcpy(emac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
      gs_emac_dev.p_hw = EMAC;
  8. Initialize EMAC device with the filled option:
    • emac_dev_init(EMAC, &gs_emac_dev, &emac_option);
  9. Enable the interrupt service for EMAC:
  10. Initialize the PHY component:
    • ethernet_phy_init(EMAC, BOARD_EMAC_PHY_ADDR, sysclk_get_cpu_hz());

The link will be established based on auto negotiation.

  • ethernet_phy_auto_negotiate(EMAC, BOARD_EMAC_PHY_ADDR);

Establish the ethernet link; the network can be worked from now on:

  • ethernet_phy_set_link(EMAC, BOARD_EMAC_PHY_ADDR, 1);

Usage steps

Example code

Add to, e.g., main loop in application C-file:

emac_dev_read(&gs_emac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));

Workflow

  1. Start reading the data from the ethernet:
    • emac_dev_read(&gs_emac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));