硬汉嵌入式论坛

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

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

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2021-1-19 08:14:41 | 显示全部楼层 |阅读模式
1、这次修改版主要是解决了网线反复插拔的问题,即我下面这个帖子的实现方法:

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


PHY_LAN8742A.c
PHY_LAN8742A.h


  1. /*
  2. * Copyright (c) 2013-2019 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:        6. May 2019
  21. * $Revision:    V1.3
  22. *  
  23. * Driver:       Driver_ETH_PHYn (default: Driver_ETH_PHY0)
  24. * Project:      Ethernet Physical Layer Transceiver (PHY)
  25. *               Driver for LAN8742A
  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 1.3
  36. *    Corrected power down bit definition
  37. *  Version 1.2
  38. *    Updated for ARM compiler 6
  39. *  Version 1.1
  40. *    Added driver flow control flags
  41. *  Version 1.0
  42. *    Initial release
  43. */

  44. #include "PHY_LAN8742A.h"

  45. #define ARM_ETH_PHY_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,3) /* driver version */


  46. #ifndef ETH_PHY_NUM
  47. #define ETH_PHY_NUM     0        /* Default driver number */
  48. #endif

  49. #ifndef ETH_PHY_ADDR
  50. #define ETH_PHY_ADDR    0x00     /* Default device address */
  51. #endif


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

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


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


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

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

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

  81.     PHY.bcr    = 0U;
  82.     PHY.flags  = PHY_INIT;
  83.   }

  84.   return ARM_DRIVER_OK;
  85. }

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

  92.   PHY.reg_rd = NULL;
  93.   PHY.reg_wr = NULL;
  94.   PHY.bcr    = 0U;
  95.   PHY.flags  = 0U;

  96.   return ARM_DRIVER_OK;
  97. }

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

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

  112.       PHY.flags &= ~PHY_POWER;
  113.       //PHY.bcr    =  BCR_POWER_DOWN;
  114.       //return (PHY.reg_wr(ETH_PHY_ADDR, REG_BCR, PHY.bcr));
  115.       
  116.       return ARM_DRIVER_OK;

  117.     case ARM_POWER_FULL:
  118.       if ((PHY.flags & PHY_INIT) == 0U) {
  119.         return ARM_DRIVER_ERROR;
  120.       }
  121.       if (PHY.flags & PHY_POWER) {
  122.         return ARM_DRIVER_OK;
  123.       }

  124.       /* Check Device Identification. */
  125.       PHY.reg_rd(ETH_PHY_ADDR, REG_PHYIDR1, &val);

  126.       if (val != PHY_ID1) {
  127.         /* Invalid PHY ID */
  128.         return ARM_DRIVER_ERROR_UNSUPPORTED;
  129.       }

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

  131.       if ((val & 0xFFF0) != PHY_ID2) {
  132.         /* Invalid PHY ID */
  133.         return ARM_DRIVER_ERROR_UNSUPPORTED;
  134.       }

  135.       PHY.bcr = 0U;

  136.       if (PHY.reg_wr(ETH_PHY_ADDR, REG_BCR, PHY.bcr) != ARM_DRIVER_OK) {
  137.         return ARM_DRIVER_ERROR;
  138.       }

  139.       PHY.flags |=  PHY_POWER;

  140.       return ARM_DRIVER_OK;

  141.     case ARM_POWER_LOW:
  142.     default:
  143.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  144.   }
  145. }

  146. /**
  147.   \fn          int32_t SetInterface (uint32_t interface)
  148.   \brief       Set Ethernet Media Interface.
  149.   \param[in]   interface  Media Interface type
  150.   \return      \ref execution_status
  151. */
  152. static int32_t SetInterface (uint32_t interface) {

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

  154.   switch (interface) {
  155.     case ARM_ETH_INTERFACE_RMII:
  156.       break;
  157.     case ARM_ETH_INTERFACE_MII:
  158.     default:
  159.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  160.   }
  161.   return(0);
  162. }

  163. /**
  164.   \fn          int32_t SetMode (uint32_t mode)
  165.   \brief       Set Ethernet PHY Device Operation mode.
  166.   \param[in]   mode  Operation Mode
  167.   \return      \ref execution_status
  168. */
  169. static int32_t SetMode (uint32_t mode) {
  170.   uint16_t val;

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

  172.   val = PHY.bcr & BCR_POWER_DOWN;

  173.   switch (mode & ARM_ETH_PHY_SPEED_Msk) {
  174.     case ARM_ETH_PHY_SPEED_10M:
  175.       break;
  176.     case ARM_ETH_PHY_SPEED_100M:
  177.       val |=  BCR_SPEED_SEL;
  178.       break;
  179.     default:
  180.       return ARM_DRIVER_ERROR_UNSUPPORTED;
  181.   }

  182.   switch (mode & ARM_ETH_PHY_DUPLEX_Msk) {
  183.     case ARM_ETH_PHY_DUPLEX_HALF:
  184.       break;
  185.     case ARM_ETH_PHY_DUPLEX_FULL:
  186.       val |=  BCR_DUPLEX;
  187.       break;
  188.   }

  189.   if (mode & ARM_ETH_PHY_AUTO_NEGOTIATE) {
  190.     val |= BCR_ANEG_EN;
  191.   }

  192.   if (mode & ARM_ETH_PHY_LOOPBACK) {
  193.     val |= BCR_LOOPBACK;
  194.   }

  195.   if (mode & ARM_ETH_PHY_ISOLATE) {
  196.     val |= BCR_ISOLATE;
  197.   }

  198.   PHY.bcr = val;

  199.   return (PHY.reg_wr(ETH_PHY_ADDR, REG_BCR, PHY.bcr));
  200. }

  201. /**
  202.   \fn          ARM_ETH_LINK_STATE GetLinkState (void)
  203.   \brief       Get Ethernet PHY Device Link state.
  204.   \return      current link status \ref ARM_ETH_LINK_STATE
  205. */
  206. static ARM_ETH_LINK_STATE GetLinkState (void) {
  207.   ARM_ETH_LINK_STATE state;
  208.   uint16_t           val = 0U;

  209.   if (PHY.flags & PHY_POWER) {
  210.     PHY.reg_rd(ETH_PHY_ADDR, REG_BSR, &val);
  211.   }
  212.   state = (val & BSR_LINK_STAT) ? ARM_ETH_LINK_UP : ARM_ETH_LINK_DOWN;

  213.   return (state);
  214. }

  215. /**
  216.   \fn          ARM_ETH_LINK_INFO GetLinkInfo (void)
  217.   \brief       Get Ethernet PHY Device Link information.
  218.   \return      current link parameters \ref ARM_ETH_LINK_INFO
  219. */
  220. static ARM_ETH_LINK_INFO GetLinkInfo (void) {
  221.   ARM_ETH_LINK_INFO info;
  222.   uint16_t          val = 0U;

  223.   if (PHY.flags & PHY_POWER) {
  224.     PHY.reg_rd(ETH_PHY_ADDR, REG_PSCS, &val);
  225.   }

  226.   info.speed  = (val & PSCS_SPEED)  ? ARM_ETH_SPEED_10M   : ARM_ETH_SPEED_100M;
  227.   info.duplex = (val & PSCS_DUPLEX) ? ARM_ETH_DUPLEX_FULL : ARM_ETH_DUPLEX_HALF;

  228.   return (info);
  229. }


  230. /* PHY Driver Control Block */
  231. extern
  232. ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM);
  233. ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM) = {
  234.   GetVersion,
  235.   Initialize,
  236.   Uninitialize,
  237.   PowerControl,
  238.   SetInterface,
  239.   SetMode,
  240.   GetLinkState,
  241.   GetLinkInfo
  242. };
复制代码


回复

使用道具 举报

6

主题

216

回帖

234

积分

高级会员

积分
234
发表于 2021-1-19 11:43:28 | 显示全部楼层
硬汉大佬推荐现在设计板子,是用8742还是8720
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2021-1-19 13:43:41 | 显示全部楼层
芯跳不止 发表于 2021-1-19 11:43
硬汉大佬推荐现在设计板子,是用8742还是8720

8742好,就是价格贵些。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 02:01 , Processed in 0.211953 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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