硬汉嵌入式论坛

 找回密码
 立即注册
查看: 325|回复: 3
收起左侧

各位大佬你们好,我想咨询一下就是我的LAN8742_Init会卡在一个循环中出不来

[复制链接]

5

主题

10

回帖

25

积分

新手上路

积分
25
发表于 2024-3-15 13:17:22 | 显示全部楼层 |阅读模式
具体为:


int32_t LAN8742_Init(lan8742_Object_t *pObj)
{
   uint32_t tickstart = 0, regvalue = 0, addr = 0;
   int32_t status = LAN8742_STATUS_OK;
   
   if(pObj->Is_Initialized == 0)
   {
     if(pObj->IO.Init != 0)
     {
       /* GPIO and Clocks initialization */
       pObj->IO.Init();
     }
   
     /* for later check */
     pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1;
   
     /* Get the device address from special mode register */  
     for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++)
     {
       if(pObj->IO.ReadReg(addr, LAN8742_SMR, &regvalue) < 0)
       {
         status = LAN8742_STATUS_READ_ERROR;
         /* Can't read from this device address
            continue with next address */
         continue;
       }
     
       if((regvalue & LAN8742_SMR_PHY_ADDR) == addr)
       {
         pObj->DevAddr = addr;
         status = LAN8742_STATUS_OK;
         break;
       }
     }
   
     if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR)
     {
       status = LAN8742_STATUS_ADDRESS_ERROR;
     }
     
     /* if device address is matched */
     if(status == LAN8742_STATUS_OK)
     {
       /* set a software reset  */
       if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0)
       {
         /* get software reset status */
         if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) >= 0)
         {
           tickstart = pObj->IO.GetTick();
           
           /* wait until software reset is done or timeout occured  */
           while(regvalue & LAN8742_BCR_SOFT_RESET)
           {
             if((pObj->IO.GetTick() - tickstart) <= LAN8742_SW_RESET_TO)
             {
               if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) < 0)
               {
                 status = LAN8742_STATUS_READ_ERROR;
                 break;
               }
             }
             else
             {
               status = LAN8742_STATUS_RESET_TIMEOUT;
               break;
             }
           }
         }
         else
         {
           status = LAN8742_STATUS_READ_ERROR;
         }
       }
       else
       {
         status = LAN8742_STATUS_WRITE_ERROR;
       }
     }
   }
      
   if(status == LAN8742_STATUS_OK)
   {
     tickstart =  pObj->IO.GetTick();
     
     /* Wait for 2s to perform initialization */
     while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO)
     {
     }
//           tx_thread_sleep(2000);
     pObj->Is_Initialized = 1;
   }
   
   return status;
}

会卡在  /* Wait for 2s to perform initialization */
     while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO)
     {
     }这一块出不来,请各位大佬指点指点
回复

使用道具 举报

5

主题

10

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-3-15 13:18:18 | 显示全部楼层
#include "dm9162.h"

lan8742_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;
lan8742_IOCtx_t  DM9162_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 = LAN8742_PHY_ADDR;
       
    printf("程序执行到这里了");
    /* Set PHY IO functions */
    LAN8742_RegisterBusIO(&DM9162, &DM9162_IOCtx);
    printf("程序meiyou执行到这里了");
    /* Initialize the DM9162 ETH PHY */
    LAN8742_Init(&DM9162);
        printf("LAN8742_Init");
    PHYLinkState = LAN8742_GetLinkState(&DM9162);
        printf("PHYLinkState = %d\r\n",PHYLinkState);
    while(PHYLinkState <= LAN8742_STATUS_LINK_DOWN)
    {
        PHYLinkState = LAN8742_GetLinkState(&DM9162);
                printf("PHYLinkStateX = %d\r\n",PHYLinkState);
        tx_thread_sleep(100);
    }

    switch (PHYLinkState)
    {
      case LAN8742_STATUS_100MBITS_FULLDUPLEX:
        duplex = ETH_MODE_FULLDUPLEX;
        speed = ETH_SPEED_100M;
        break;
      case LAN8742_STATUS_100MBITS_HALFDUPLEX:
        duplex = ETH_MODE_HALFDUPLEX;
        speed = ETH_SPEED_100M;
        break;
      case LAN8742_STATUS_10MBITS_FULLDUPLEX:
        duplex = ETH_MODE_FULLDUPLEX;
        speed = ETH_SPEED_10M;
        break;
      case LAN8742_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[i];

#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[i].Buffer1Addr =          (uint32_t) packet_ptr -> nx_packet_prepend_ptr;
            DMARxDesc[i].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[i] =  packet_ptr;

            /* Set Own bit of the RX descriptor Status.  */
            DMARxDesc[i].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[i].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[i].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);       
头文件没动,但是LAN8742的内容全都加进去了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2024-3-16 09:36:23 | 显示全部楼层
有个重要的地方,当前硬件设计8720的复位是怎么设计的,和系统一个硬件复位还是单独的GPIO控制的。
回复

使用道具 举报

5

主题

10

回帖

25

积分

新手上路

积分
25
 楼主| 发表于 2024-3-16 09:57:03 | 显示全部楼层
eric2013 发表于 2024-3-16 09:36
有个重要的地方,当前硬件设计8720的复位是怎么设计的,和系统一个硬件复位还是单独的GPIO控制的。

大哥是单独的GPIO控制的,我昨天最终找到问题了 是HAL_GetTICK()函数的问题,在等待2S的过程中,tucjstart一直没返回数值,最终发送延时函数那边[img][/img],更改后,可以直接进行硬件初始化并进行后续功能了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-2 06:44 , Processed in 0.299537 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表