cancel
Showing results for 
Search instead for 
Did you mean: 

lwIP - TCP echo server in STM32F769-Discovery

Omar Suárez
Senior
Posted on February 22, 2018 at 16:21

Hello,

I am trying to make an example application consisting in a TCP echo server using the RAW from the lwIP stack just to understand how it works. I am using the STM32F769NI - Discovery board as the target which mounts the PHY LAN8742A. I am using the examples in the STM32F7Cube HAL to prepare my project but I am a stuck in the ethernetif.c file.

I can find some examples in the F7Cube HAL using the EVAL boards but those mount a different PHY (DP83848) and also in the F4Cube HAL but with the same problem, different PHY. The fact is that the PHY are different one from another so I can not use the 'hal_conf.h' code with the PHY registers as in those examples. I need to change the use of the registers and the configuration of the interrupts from the PHY.

I am new to the lwIP so I am not sure how to configure the Discovery PHY to use it in the same way as the one in the EVAL boards.

Below I attach the code for the two functions inside the 'eterhnetif.c' file which use those registers (defined in the hal_conf.h) to set up the interrupts needed for this TCP echo application.

/* ethernetif.c file */

...

...

/**

  * @brief  This function sets the netif link status.

  * @param  netif: the network interface

  * @retval None

  */

void ethernetif_set_link(struct netif *netif)

{

  uint32_t regvalue = 0;

 

  /* Read PHY_MISR*/

  HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MISR, &regvalue);

 

  /* Check whether the link interrupt has occurred or not */

  if((regvalue & PHY_LINK_INTERRUPT) != (uint16_t)RESET)

  {

    /* Read PHY_SR*/

    HAL_ETH_ReadPHYRegister(&EthHandle, PHY_SR, &regvalue);

    

    /* Check whether the link is up or down*/

    if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)

    {

      netif_set_link_up(netif);

    }

    else

    {

      netif_set_link_down(netif);

    }

  }

}

/* ethernetif.c file */

...

...

...

/**

  * @brief In this function, the hardware should be initialized.

  * Called from ethernetif_init().

  *

  * @param netif the already initialized lwip network interface structure

  *        for this ethernetif

  */

static void low_level_init(struct netif *netif)

{

  uint32_t regvalue = 0;

  uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 };

 

  EthHandle.Instance = ETH;  

  EthHandle.Init.MACAddr = macaddress;

  EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;

  EthHandle.Init.Speed = ETH_SPEED_100M;

  EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;

  EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;

  EthHandle.Init.RxMode = ETH_RXPOLLING_MODE;

  EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;

  EthHandle.Init.PhyAddress = DP83848_PHY_ADDRESS;

 

  /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */

  if (HAL_ETH_Init(&EthHandle) == HAL_OK)

  {

    /* Set netif link flag */

    netif->flags |= NETIF_FLAG_LINK_UP;

  }

 

  /* Initialize Tx Descriptors list: Chain Mode */

  HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);

     

  /* Initialize Rx Descriptors list: Chain Mode  */

  HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);

 

  /* set MAC hardware address length */

  netif->hwaddr_len = ETH_HWADDR_LEN;

 

  /* set MAC hardware address */

  netif->hwaddr[0] =  MAC_ADDR0;

  netif->hwaddr[1] =  MAC_ADDR1;

  netif->hwaddr[2] =  MAC_ADDR2;

  netif->hwaddr[3] =  MAC_ADDR3;

  netif->hwaddr[4] =  MAC_ADDR4;

  netif->hwaddr[5] =  MAC_ADDR5;

 

  /* maximum transfer unit */

  netif->mtu = 1500;

 

  /* device capabilities */

  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */

  netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;

 

  /* Enable MAC and DMA transmission and reception */

  HAL_ETH_Start(&EthHandle);

 

  /**** Configure PHY to generate an interrupt when Eth Link state changes ****/

  /* Read Register Configuration */

  HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MICR, &regvalue);

 

  regvalue |= (PHY_MICR_INT_EN | PHY_MICR_INT_OE);

  /* Enable Interrupts */

  HAL_ETH_WritePHYRegister(&EthHandle, PHY_MICR, regvalue );

 

  /* Read Register Configuration */

  HAL_ETH_ReadPHYRegister(&EthHandle, PHY_MISR, &regvalue);

 

  regvalue |= PHY_MISR_LINK_INT_EN;

    

  /* Enable Interrupt on change of link status */

  HAL_ETH_WritePHYRegister(&EthHandle, PHY_MISR, regvalue);

}

Anyone has configured a project to work as TCP echo server using the Discovery board or the PHY mounted on it (LAN8742A)? How can I configure the PHY to work the same way as in the EVAL board application?

Thanks in advanced,

Omar

#ethernet-stm32f7 #stm32f7-hal #phy #tcp/ip
1 REPLY 1
Omar Suárez
Senior
Posted on February 22, 2018 at 16:23

Note that the registers configured in the DP83848 are PHY_SR, PHY_MISR and PHY_MICR.