AnsweredAssumed Answered

lwIP - TCP echo server in STM32F769-Discovery

Question asked by Omar Suárez on Feb 22, 2018
Latest reply on Feb 22, 2018 by Omar Suárez

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

Outcomes