硬汉嵌入式论坛

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

[ETH PHY] 分享修正版RL-TCPnet V7.X和LwIP的LAN8720驱动,符合CMSIS-Driver驱动规范,适用于所有STM32系列(V1.1修正版)

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2021-1-19 07:58:04 | 显示全部楼层 |阅读模式
1、之前分享了V1.0版,这次再分享个V1.1版本:

分享个修正版RL-TCPnet V7.X和LwIP的LAN8720驱动,符合CMSIS-Driver驱动规范,适用于所有STM32系列(V1.0)
http://www.armbbs.cn/forum.php?mod=viewthread&tid=97297


2、这次修改版主要是解决了网线反复插拔的问题,即我下面这个帖子的实现方法:

【实战经验分享】一劳永逸的解决网线随意热插拔问题
http://www.armbbs.cn/forum.php?mod=viewthread&tid=95386



PHY_LAN8720.c
PHY_LAN8720.h


  1. /*
  2. * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------
  19. *
  20. * $Date:        25. May 2018
  21. * $Revision:    V6.2
  22. *  
  23. * Driver:       Driver_ETH_PHYn (default: Driver_ETH_PHY0)
  24. * Project:      Ethernet Physical Layer Transceiver (PHY)
  25. *               Driver for LAN8720
  26. * -----------------------------------------------------------------------
  27. * Use the following configuration settings in the middleware component
  28. * to connect to this driver.
  29. *
  30. *   Configuration Setting                     Value
  31. *   ---------------------                     -----
  32. *   Connect to hardware via Driver_ETH_PHY# = n (default: 0)
  33. * -------------------------------------------------------------------- */

  34. /* History:
  35. *  Version 6.2
  36. *    Updated for ARM compiler 6
  37. *  Version 6.1
  38. *    Added driver flow control flags
  39. *  Version 6.00
  40. *    Based on API V2.00
  41. *  Version 5.01
  42. *    Based on API V1.10 (namespace prefix ARM_ added)
  43. *  Version 5.00
  44. *    Initial release
  45. */

  46. #include "PHY_LAN8720.h"

  47. #define ARM_ETH_PHY_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(6,2) /* driver version */


  48. #ifndef ETH_PHY_NUM
  49. #define ETH_PHY_NUM     0        /* Default driver number */
  50. #endif

  51. #ifndef ETH_PHY_ADDR
  52. #define ETH_PHY_ADDR    0x00     /* Default device address */
  53. #endif


  54. /* Driver Version */
  55. static const ARM_DRIVER_VERSION DriverVersion = {
  56.   ARM_ETH_PHY_API_VERSION,
  57.   ARM_ETH_PHY_DRV_VERSION
  58. };

  59. /* Ethernet PHY control structure */
  60. static PHY_CTRL PHY = { NULL, NULL, 0, 0, 0 };


  61. /**
  62.   \fn          ARM_DRIVER_VERSION GetVersion (void)
  63.   \brief       Get driver version.
  64.   \return      \ref ARM_DRIVER_VERSION
  65. */
  66. static ARM_DRIVER_VERSION GetVersion (void) {
  67.   return DriverVersion;
  68. }


  69. /**
  70.   \fn          int32_t Initialize (ARM_ETH_PHY_Read_t  fn_read,
  71.                                    ARM_ETH_PHY_Write_t fn_write)
  72.   \brief       Initialize Ethernet PHY Device.
  73.   \param[in]   fn_read   Pointer to \ref ARM_ETH_MAC_PHY_Read
  74.   \param[in]   fn_write  Pointer to \ref ARM_ETH_MAC_PHY_Write
  75.   \return      \ref execution_status
  76. */
  77. static int32_t Initialize (ARM_ETH_PHY_Read_t fn_read, ARM_ETH_PHY_Write_t fn_write) {

  78.   if ((fn_read == NULL) || (fn_write == NULL)) { return ARM_DRIVER_ERROR_PARAMETER; }

  79.   if ((PHY.flags & PHY_INIT) == 0U) {
  80.     /* Register PHY read/write functions. */
  81.     PHY.reg_rd = fn_read;
  82.     PHY.reg_wr = fn_write;

  83.     PHY.bmcr   = 0U;
  84.     PHY.flags  = PHY_INIT;
  85.   }

  86.   return ARM_DRIVER_OK;
  87. }

  88. /**
  89.   \fn          int32_t Uninitialize (void)
  90.   \brief       De-initialize Ethernet PHY Device.
  91.   \return      \ref execution_status
  92. */
  93. static int32_t Uninitialize (void) {

  94.   PHY.reg_rd = NULL;
  95.   PHY.reg_wr = NULL;
  96.   PHY.bmcr   = 0U;
  97.   PHY.flags  = 0U;

  98.   return ARM_DRIVER_OK;
  99. }

  100. /**
  101.   \fn          int32_t PowerControl (ARM_POWER_STATE state)
  102.   \brief       Control Ethernet PHY Device Power.
  103.   \param[in]   state  Power state
  104.   \return      \ref execution_status
  105. */
  106. static int32_t PowerControl (ARM_POWER_STATE state) {
  107.   uint16_t val;

  108.   switch ((int32_t)state) {
  109.     case ARM_POWER_OFF:
  110.       if ((PHY.flags & PHY_INIT) == 0U) {
  111.         /* Initialize must provide register access function pointers */
  112.         return ARM_DRIVER_ERROR;
  113.       }

  114.       PHY.flags &= ~PHY_POWER;

  115.      #if 0
  116.       PHY.bmcr   &=  ~BMCR_ANEG_EN;
  117.       PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr);

  118.       PHY.bmcr   |=  BMCR_POWER_DOWN;
  119.       PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr);
  120.       uint32_t tout;
  121.       
  122.         for (tout = 0; tout < 0x1000; tout++)
  123.         {
  124.             PHY.reg_rd(ETH_PHY_ADDR, REG_BMCR, &val);
  125.             if (!(val & 0x0800))
  126.             {
  127.                 break;
  128.             }
  129.         }
  130.         
  131.         PHY.bmcr  =  0;
  132.         PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr);
  133.         return ARM_DRIVER_OK;
  134.       #endif
  135.       
  136.       #if 0
  137.         PHY.bmcr   =  BMCR_POWER_DOWN;
  138.         return (PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr));
  139.       #endif

  140.       #if 1
  141.         return ARM_DRIVER_OK;
  142.       #endif

  143.     case ARM_POWER_FULL:
  144.       if ((PHY.flags & PHY_INIT) == 0U) {
  145.         return ARM_DRIVER_ERROR;
  146.       }
  147.       if (PHY.flags & PHY_POWER) {
  148.         return ARM_DRIVER_OK;
  149.       }
  150.           
  151.           {
  152.                 uint32_t tout;
  153.          
  154.                 PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, BMCR_RESET);
  155.                 for (tout = 0; tout < 0x100000; tout++)
  156.                 {
  157.                         PHY.reg_rd(ETH_PHY_ADDR, REG_BMCR, &val);
  158.                         if (!(val & 0x8000))
  159.                         {
  160.                                 break;
  161.                         }
  162.                 }
  163.           
  164.           }
  165.           
  166.       /* Check Device Identification. */
  167.       PHY.reg_rd(ETH_PHY_ADDR, REG_PHYIDR1, &val);

  168.       if (val != PHY_ID1) {
  169.         /* Invalid PHY ID */
  170.         return ARM_DRIVER_ERROR_UNSUPPORTED;
  171.       }

  172.       PHY.reg_rd(ETH_PHY_ADDR, REG_PHYIDR2, &val);

  173.       if ((val & 0xFFF0) != PHY_ID2) {
  174.         /* Invalid PHY ID */
  175.         return ARM_DRIVER_ERROR_UNSUPPORTED;
  176.       }

  177.       PHY.bmcr = 0U;

  178.       if (PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr) != ARM_DRIVER_OK) {
  179.         return ARM_DRIVER_ERROR;
  180.       }

  181.       PHY.flags |=  PHY_POWER;

  182.       return ARM_DRIVER_OK;

  183.     case ARM_POWER_LOW:
  184.     default:
  185.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  186.   }
  187. }

  188. /**
  189.   \fn          int32_t SetInterface (uint32_t interface)
  190.   \brief       Set Ethernet Media Interface.
  191.   \param[in]   interface  Media Interface type
  192.   \return      \ref execution_status
  193. */
  194. static int32_t SetInterface (uint32_t interface) {

  195.   if ((PHY.flags & PHY_POWER) == 0U) { return ARM_DRIVER_ERROR; }

  196.   switch (interface) {
  197.     case ARM_ETH_INTERFACE_RMII:
  198.       break;
  199.     case ARM_ETH_INTERFACE_MII:
  200.     default:
  201.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  202.   }
  203.   return(0);
  204. }

  205. /**
  206.   \fn          int32_t SetMode (uint32_t mode)
  207.   \brief       Set Ethernet PHY Device Operation mode.
  208.   \param[in]   mode  Operation Mode
  209.   \return      \ref execution_status
  210. */
  211. static int32_t SetMode (uint32_t mode) {
  212.   uint16_t val;

  213.   if ((PHY.flags & PHY_POWER) == 0U) { return ARM_DRIVER_ERROR; }

  214.   val = PHY.bmcr & BMCR_POWER_DOWN;

  215.   switch (mode & ARM_ETH_PHY_SPEED_Msk) {
  216.     case ARM_ETH_PHY_SPEED_10M:
  217.       break;
  218.     case ARM_ETH_PHY_SPEED_100M:
  219.       val |=  BMCR_SPEED_SEL;
  220.       break;
  221.     default:
  222.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  223.   }

  224.   switch (mode & ARM_ETH_PHY_DUPLEX_Msk) {
  225.     case ARM_ETH_PHY_DUPLEX_HALF:
  226.       break;
  227.     case ARM_ETH_PHY_DUPLEX_FULL:
  228.       val |=  BMCR_DUPLEX;
  229.       break;
  230.   }

  231.   if (mode & ARM_ETH_PHY_AUTO_NEGOTIATE) {
  232.     val |= BMCR_ANEG_EN;
  233.   }

  234.   if (mode & ARM_ETH_PHY_LOOPBACK) {
  235.     val |= BMCR_LOOPBACK;
  236.   }

  237.   if (mode & ARM_ETH_PHY_ISOLATE) {
  238.     val |= BMCR_ISOLATE;
  239.   }

  240.   PHY.bmcr = val;

  241.   return (PHY.reg_wr(ETH_PHY_ADDR, REG_BMCR, PHY.bmcr));
  242. }

  243. /**
  244.   \fn          ARM_ETH_LINK_STATE GetLinkState (void)
  245.   \brief       Get Ethernet PHY Device Link state.
  246.   \return      current link status \ref ARM_ETH_LINK_STATE
  247. */
  248. static ARM_ETH_LINK_STATE GetLinkState (void) {
  249.   ARM_ETH_LINK_STATE state;
  250.   uint16_t           val = 0U;

  251.   if (PHY.flags & PHY_POWER) {
  252.     PHY.reg_rd(ETH_PHY_ADDR, REG_BMSR, &val);
  253.   }
  254.   state = (val & BMSR_LINK_STAT) ? ARM_ETH_LINK_UP : ARM_ETH_LINK_DOWN;

  255.   return (state);
  256. }

  257. /**
  258.   \fn          ARM_ETH_LINK_INFO GetLinkInfo (void)
  259.   \brief       Get Ethernet PHY Device Link information.
  260.   \return      current link parameters \ref ARM_ETH_LINK_INFO
  261. */
  262. static ARM_ETH_LINK_INFO GetLinkInfo (void) {
  263.   ARM_ETH_LINK_INFO info;
  264.   uint16_t          val = 0U;

  265.   if (PHY.flags & PHY_POWER) {
  266.     PHY.reg_rd(ETH_PHY_ADDR, REG_PSCSR, &val);
  267.   }

  268.   info.speed  = (val & PSCSR_SPEED)  ? ARM_ETH_SPEED_10M   : ARM_ETH_SPEED_100M;
  269.   info.duplex = (val & PSCSR_DUPLEX) ? ARM_ETH_DUPLEX_FULL : ARM_ETH_DUPLEX_HALF;

  270.   return (info);
  271. }


  272. /* PHY Driver Control Block */
  273. extern
  274. ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM);
  275. ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM) = {
  276.   GetVersion,
  277.   Initialize,
  278.   Uninitialize,
  279.   PowerControl,
  280.   SetInterface,
  281.   SetMode,
  282.   GetLinkState,
  283.   GetLinkInfo
  284. };
复制代码


回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 01:57 , Processed in 0.146762 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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