eric2013 发表于 2021-3-24 10:46:41

ThreadX NetXDUO上电未插入网线的解决办法

在底层驱动这里先初始化PHY芯片即可,然后等待网线插入。

F4和H7的ETH的HAL版驱动略有不同,但处理方法是一样的。

关键部分:

    /* Initialize the DM9162 ETH PHY */
    DM9162_Init(&DM9162);

    PHYLinkState = DM9162_GetLinkState(&DM9162);

    while(PHYLinkState <= DM9162_STATUS_LINK_DOWN)
    {
      PHYLinkState = DM9162_GetLinkState(&DM9162);
      tx_thread_sleep(100);
    }

完整:

/* 这里直接将相对变量和头文件都放在这里 */
#include "dm9162.h"

dm9162_Object_t DM9162;
TX_THREAD *netx_thread_ptr;

static UINT_nx_driver_hardware_initialize(NX_IP_DRIVER *driver_req_ptr)
{
INT PHYLinkState;
UINT duplex, speed = 0;
dm9162_IOCtx_tDM9162_IOCtx = {ETH_PHY_IO_Init,
                               ETH_PHY_IO_DeInit,
                               ETH_PHY_IO_WriteReg,
                               ETH_PHY_IO_ReadReg,
                               ETH_PHY_IO_GetTick};
NX_PACKET         *packet_ptr;
UINT                i;
ETH_DMADescTypeDef*DMATxDesc;
ETH_DMADescTypeDef*DMARxDesc = nx_driver_information.nx_driver_information_dma_rx_descriptors;


    HAL_ETH_MspInit(NULL);
                              
    /* Default to successful return.*/
    driver_req_ptr -> nx_ip_driver_status =NX_SUCCESS;

    /* Setup indices.*/
    nx_driver_information.nx_driver_information_receive_current_index = 0;
    nx_driver_information.nx_driver_information_transmit_current_index = 0;
    nx_driver_information.nx_driver_information_transmit_release_index = 0;

    /* Clear the number of buffers in use counter.*/
    nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use = 0;

    /* Make sure there are receive packets... otherwise, return an error.*/
    if (nx_driver_information.nx_driver_information_packet_pool_ptr == NULL)
    {
   
      /* There must be receive packets. If not, return an error!*/
      return(NX_DRIVER_ERROR);
    }
   
    EthHandle.Instance = ETH;
    EthHandle.Init.MACAddr = _nx_driver_hardware_address;
    EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
    EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
    EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
    EthHandle.Init.PhyAddress = DM9162_PHY_ADDR;
   
    /* Set PHY IO functions */
    DM9162_RegisterBusIO(&DM9162, &DM9162_IOCtx);
   
    /* Initialize the DM9162 ETH PHY */
    DM9162_Init(&DM9162);

    PHYLinkState = DM9162_GetLinkState(&DM9162);

    while(PHYLinkState <= DM9162_STATUS_LINK_DOWN)
    {
      PHYLinkState = DM9162_GetLinkState(&DM9162);
      tx_thread_sleep(100);
    }

    switch (PHYLinkState)
    {
      case DM9162_STATUS_100MBITS_FULLDUPLEX:
      duplex = ETH_MODE_FULLDUPLEX;
      speed = ETH_SPEED_100M;
      break;
      case DM9162_STATUS_100MBITS_HALFDUPLEX:
      duplex = ETH_MODE_HALFDUPLEX;
      speed = ETH_SPEED_100M;
      break;
      case DM9162_STATUS_10MBITS_FULLDUPLEX:
      duplex = ETH_MODE_FULLDUPLEX;
      speed = ETH_SPEED_10M;
      break;
      case DM9162_STATUS_10MBITS_HALFDUPLEX:
      duplex = ETH_MODE_HALFDUPLEX;
      speed = ETH_SPEED_10M;
      break;
      default:
      duplex = ETH_MODE_FULLDUPLEX;
      speed = ETH_SPEED_100M;
      break;
    }
   
    EthHandle.Init.Speed = speed;
    EthHandle.Init.DuplexMode = duplex;

    /* Configure Ethernet peripheral (GPIOs, clocks, MAC, DMA) */
    if (HAL_ETH_Init(&EthHandle) != HAL_OK)
    {
      /* Return error.*/
      return(NX_DRIVER_ERROR);
    }

    /* Initialize TX Descriptors list: Ring Mode.*/

    /* Fill each DMATxDesc descriptor with the right values.*/   
    for(i = 0; i < NX_DRIVER_TX_DESCRIPTORS; i++)
    {
      /* Get the pointer on the ith member of the Tx Desc list.*/
      DMATxDesc = &nx_driver_information.nx_driver_information_dma_tx_descriptors;

#ifdef HARDWARE_CHECKSUM_ENABLE

      /* Set Second Address Chained bit and checksum offload options.*/
      DMATxDesc -> Status = ETH_DMATXDESC_TCH | ETH_DMATXDESC_IC | ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_CIC_IPV4HEADER;      
#else

      /* Set Second Address Chained bit.*/
      DMATxDesc -> Status = ETH_DMATXDESC_TCH | ETH_DMATXDESC_IC;      
#endif

      /* Initialize the next descriptor with the Next Descriptor Polling Enable */
      if(i < (NX_DRIVER_TX_DESCRIPTORS - 1))
      {
            /* Set next descriptor address register with next descriptor base address */
            DMATxDesc -> Buffer2NextDescAddr = (ULONG)(nx_driver_information.nx_driver_information_dma_tx_descriptors + i + 1);
      }
      else
      {
            /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
            DMATxDesc -> Buffer2NextDescAddr = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors;
      }
    }
   
    /* Set Transmit Descriptor List Address Register */
    ETH -> DMATDLAR = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors;

    /* Initialize RX Descriptors list: Ring Mode*/

    /* Fill each DMARxDesc descriptor with the right values */
    for(i = 0; i < NX_DRIVER_RX_DESCRIPTORS; i++)
    {

      /* Allocate a packet for the receive buffers.*/
      if (nx_packet_allocate(nx_driver_information.nx_driver_information_packet_pool_ptr, &packet_ptr,
                               NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
      {

            /* Adjust the packet.*/
            packet_ptr -> nx_packet_prepend_ptr += 2;
            DMARxDesc.Buffer1Addr =          (uint32_t) packet_ptr -> nx_packet_prepend_ptr;
            DMARxDesc.ControlBufferSize =    ETH_DMARXDESC_RCH | (packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start);

            /* Remember the receive packet poitner.*/
            nx_driver_information.nx_driver_information_receive_packets =packet_ptr;

            /* Set Own bit of the RX descriptor Status.*/
            DMARxDesc.Status =ETH_DMARXDESC_OWN;         
      }
      else
      {

            /* Cannot allocate packets from the packet pool. */
            return(NX_DRIVER_ERROR);
      }

      /* Initialize the next descriptor with the Next Descriptor Polling Enable.*/
      if(i < (NX_DRIVER_RX_DESCRIPTORS - 1))
      {
            /* Set next descriptor address register with next descriptor base address.*/
            DMARxDesc.Buffer2NextDescAddr = (ULONG)(nx_driver_information.nx_driver_information_dma_rx_descriptors + i + 1);
      }
      else
      {
            /* For last descriptor, set next descriptor address register equal to the first descriptor base address.*/
            DMARxDesc.Buffer2NextDescAddr = (uint32_t)(nx_driver_information.nx_driver_information_dma_rx_descriptors);
      }
    }
   
    /* Save the size of one rx buffer.*/
    nx_driver_information.nx_driver_information_rx_buffer_size = packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start;
      
    /* Clear the number of buffers in use counter.*/
    nx_driver_information.nx_driver_information_multicast_count = 0;

    /* Set Receive Descriptor List Address Register */
    ETH -> DMARDLAR = (ULONG) nx_driver_information.nx_driver_information_dma_rx_descriptors;

    /* Return success!*/
    return(NX_SUCCESS);
}


hpdell 发表于 2021-3-24 15:07:59

如果中途吧网线拔掉 或者断电了,有什么好的解决方法 啊 ?

eric2013 发表于 2021-3-24 15:21:08

hpdell 发表于 2021-3-24 15:07
如果中途吧网线拔掉 或者断电了,有什么好的解决方法 啊 ?

中途插拔,我准备采用我此贴的方案:

【实战经验分享】一劳永逸的解决网线随意热插拔问题
http://www.armbbs.cn/forum.php?mod=viewthread&tid=95386&fromuid=58
(出处: 硬汉嵌入式论坛)

hpdell 发表于 2021-3-24 16:54:49

eric2013 发表于 2021-3-24 15:21
中途插拔,我准备采用我此贴的方案:

【实战经验分享】一劳永逸的解决网线随意热插拔问题


好哇,期待大神的完整作品啊,辛苦大神了

jacksimcom 发表于 2021-7-20 17:25:25

好像NetX没发现类似的函数来notify,是不是需要自己创建任务调用LAN8742_GetLinkState(&lan8742);来获取网线插拔状态啊

eric2013 发表于 2021-7-21 09:17:23

jacksimcom 发表于 2021-7-20 17:25
好像NetX没发现类似的函数来notify,是不是需要自己创建任务调用LAN8742_GetLinkState(&lan8742);来获取网 ...

对,我是这么玩的。

NetX的原装玩法,我还没有研究。

ihavedone 发表于 2021-7-23 10:17:09

用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线都是暗亮,连不上网络,大家有遇到过吗? 是什么原因呢?

eric2013 发表于 2021-7-23 14:53:16

ihavedone 发表于 2021-7-23 10:17
用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线 ...

你的意思是用其它网络协议栈正常?

hpdell 发表于 2021-7-24 18:26:16

ihavedone 发表于 2021-7-23 10:17
用NETX DUO做网络功能,PHY 芯片是 LAN8720。现在遇到个问题,上电之后 网口的两个灯都是暗亮,插不插网线 ...

估计硬件有问题吧 ??

Jarm 发表于 2023-12-6 11:52:28

楼主,请问现在有NETXDUO的网线插拔解决方案吗?求

eric2013 发表于 2023-12-6 12:12:37

Jarm 发表于 2023-12-6 11:52
楼主,请问现在有NETXDUO的网线插拔解决方案吗?求

现在还没有一劳永逸的方案。

现在的机制式定期查询网线插拔状态,来对程序做处理

way2888 发表于 2023-12-7 20:42:38

要重新初始化的话,必须要把所有的端口释放才可以,不知道有什么办法更便捷呢?
页: [1]
查看完整版本: ThreadX NetXDUO上电未插入网线的解决办法