Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 

214 рядки
7.0 KiB

  1. #include "lan8720.h"
  2. #include "lwip_comm.h"
  3. #include "delay.h"
  4. #include "malloc.h"
  5. #include "usart.h"
  6. //////////////////////////////////////////////////////////////////////////////////
  7. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  8. //ALIENTEK STM32F7开发板
  9. //LAN8720驱动代码
  10. //正点原子@ALIENTEK
  11. //技术论坛:www.openedv.com
  12. //创建日期:2016/1/13
  13. //版本:V1.0
  14. //版权所有,盗版必究。
  15. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
  16. //All rights reserved
  17. //////////////////////////////////////////////////////////////////////////////////
  18. ETH_HandleTypeDef ETH_Handler; //以太网句柄
  19. ETH_DMADescTypeDef *DMARxDscrTab; //以太网DMA接收描述符数据结构体指针
  20. ETH_DMADescTypeDef *DMATxDscrTab; //以太网DMA发送描述符数据结构体指针
  21. uint8_t *Rx_Buff; //以太网底层驱动接收buffers指针
  22. uint8_t *Tx_Buff; //以太网底层驱动发送buffers指针
  23. //LAN8720初始化
  24. //返回值:0,成功;
  25. // 其他,失败
  26. u8 LAN8720_Init(void)
  27. {
  28. u8 macaddress[6];
  29. // INTX_DISABLE(); //关闭所有中断,复位过程不能被打断!
  30. // HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3, GPIO_PIN_RESET); //硬件复位
  31. // delay_ms(100);
  32. // HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3, GPIO_PIN_SET); //复位结束
  33. // delay_ms(100);
  34. // INTX_ENABLE(); //开启所有中断
  35. macaddress[0] = lwipdev.mac[0];
  36. macaddress[1] = lwipdev.mac[1];
  37. macaddress[2] = lwipdev.mac[2];
  38. macaddress[3] = lwipdev.mac[3];
  39. macaddress[4] = lwipdev.mac[4];
  40. macaddress[5] = lwipdev.mac[5];
  41. ETH_Handler.Instance = ETH;
  42. ETH_Handler.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE; //使能自协商模式
  43. ETH_Handler.Init.Speed = ETH_SPEED_100M; //速度100M,如果开启了自协商模式,此配置就无效
  44. ETH_Handler.Init.DuplexMode = ETH_MODE_FULLDUPLEX; //全双工模式,如果开启了自协商模式,此配置就无效
  45. ETH_Handler.Init.PhyAddress = LAN8720_PHY_ADDRESS; //LAN8720地址
  46. ETH_Handler.Init.MACAddr = macaddress; //MAC地址
  47. ETH_Handler.Init.RxMode = ETH_RXINTERRUPT_MODE; //中断接收模式
  48. ETH_Handler.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; //硬件帧校验
  49. ETH_Handler.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; //RMII接口
  50. if (HAL_ETH_Init(&ETH_Handler) == HAL_OK)
  51. {
  52. printf("初始化成功\r\n");
  53. return 0; //成功
  54. }
  55. else
  56. {
  57. printf("初始化失败\r\n");
  58. return 1; //失败
  59. }
  60. }
  61. //ETH底层驱动,时钟使能,引脚配置
  62. //此函数会被HAL_ETH_Init()调用
  63. //heth:以太网句柄
  64. void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
  65. {
  66. GPIO_InitTypeDef GPIO_Initure;
  67. __HAL_RCC_ETH_CLK_ENABLE(); //开启ETH时钟
  68. __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
  69. __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
  70. __HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
  71. __HAL_RCC_GPIOD_CLK_ENABLE(); //开启GPIOD时钟
  72. __HAL_RCC_GPIOG_CLK_ENABLE(); //开启GPIOG时钟
  73. /*网络引脚设置 RMII接口
  74. ETH_MDIO -------------------------> PA2
  75. ETH_MDC --------------------------> PC1
  76. ETH_RMII_REF_CLK------------------> PA1
  77. ETH_RMII_CRS_DV ------------------> PA7
  78. ETH_RMII_RXD0 --------------------> PC4
  79. ETH_RMII_RXD1 --------------------> PC5
  80. ETH_RMII_TX_EN -------------------> PG11
  81. ETH_RMII_TXD0 --------------------> PB12
  82. ETH_RMII_TXD1 --------------------> PB13
  83. ETH_RESET-------------------------> PD3*/
  84. //PA1,2,7
  85. GPIO_Initure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
  86. GPIO_Initure.Mode = GPIO_MODE_AF_PP; //推挽复用
  87. GPIO_Initure.Pull = GPIO_NOPULL; //不带上下拉
  88. GPIO_Initure.Speed = GPIO_SPEED_HIGH; //高速
  89. GPIO_Initure.Alternate = GPIO_AF11_ETH; //复用为ETH功能
  90. HAL_GPIO_Init(GPIOA, &GPIO_Initure); //初始化
  91. //PB12,13
  92. GPIO_Initure.Pin = GPIO_PIN_12|GPIO_PIN_13; //PB12,13
  93. HAL_GPIO_Init(GPIOB, &GPIO_Initure); //始化
  94. //PC1,4,5
  95. GPIO_Initure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; //PC1,4,5
  96. HAL_GPIO_Init(GPIOC, &GPIO_Initure); //初始化
  97. //PG11
  98. GPIO_Initure.Pin = GPIO_PIN_11; //PG11
  99. HAL_GPIO_Init(GPIOG, &GPIO_Initure); //初始化
  100. //配置PD3为推挽输出
  101. GPIO_Initure.Pin = GPIO_PIN_3;
  102. GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出
  103. GPIO_Initure.Pull = GPIO_NOPULL; //不带上下拉
  104. GPIO_Initure.Speed = GPIO_SPEED_HIGH; //高速
  105. HAL_GPIO_Init(GPIOD,&GPIO_Initure);
  106. //硬件复位网口芯片
  107. INTX_DISABLE(); //关闭所有中断,复位过程不能被打断!
  108. HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_RESET);
  109. delay_ms(50);
  110. HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_SET);
  111. delay_ms(50);
  112. INTX_ENABLE(); //开启所有中断
  113. HAL_NVIC_SetPriority(ETH_IRQn, 1, 0); //网络中断优先级应该高一点
  114. HAL_NVIC_EnableIRQ(ETH_IRQn);
  115. }
  116. //读取PHY寄存器值
  117. u32 LAN8720_ReadPHY(u16 reg)
  118. {
  119. u32 regval;
  120. HAL_ETH_ReadPHYRegister(&ETH_Handler, reg, &regval);
  121. return regval;
  122. }
  123. //向LAN8720指定寄存器写入值
  124. //reg:要写入的寄存器
  125. //value:要写入的值
  126. void LAN8720_WritePHY(u16 reg, u16 value)
  127. {
  128. u32 temp = value;
  129. HAL_ETH_ReadPHYRegister(&ETH_Handler, reg, &temp);
  130. }
  131. //得到8720的速度模式
  132. //返回值:
  133. //001:10M半双工
  134. //101:10M全双工
  135. //010:100M半双工
  136. //110:100M全双工
  137. //其他:错误.
  138. u8 LAN8720_Get_Speed(void)
  139. {
  140. u8 speed;
  141. speed = ((LAN8720_ReadPHY(31) & 0x1C) >> 2); //从LAN8720的31号寄存器中读取网络速度和双工模式
  142. return speed;
  143. }
  144. //extern void lwip_pkt_handle(void); //在lwip_comm.c里面定义
  145. //中断服务函数
  146. void ETH_IRQHandler(void)
  147. {
  148. while (ETH_GetRxPktSize(ETH_Handler.RxDesc))
  149. {
  150. lwip_pkt_handle(); //处理以太网数据,即将数据提交给LWIP
  151. }
  152. //清除中断标志位
  153. __HAL_ETH_DMA_CLEAR_IT(&ETH_Handler, ETH_DMA_IT_NIS); //清除DMA中断标志位
  154. __HAL_ETH_DMA_CLEAR_IT(&ETH_Handler, ETH_DMA_IT_R); //清除DMA接收中断标志位
  155. }
  156. //获取接收到的帧长度
  157. //DMARxDesc:接收DMA描述符
  158. //返回值:接收到的帧长度
  159. u32 ETH_GetRxPktSize(ETH_DMADescTypeDef *DMARxDesc)
  160. {
  161. u32 frameLength = 0;
  162. if (((DMARxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
  163. ((DMARxDesc->Status & ETH_DMARXDESC_ES) == (uint32_t)RESET) &&
  164. ((DMARxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET))
  165. {
  166. frameLength = ((DMARxDesc->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
  167. }
  168. return frameLength;
  169. }
  170. //为ETH底层驱动申请内存
  171. //返回值:0,正常
  172. // 其他,失败
  173. u8 ETH_Mem_Malloc(void)
  174. {
  175. DMARxDscrTab = mymalloc(SRAMDTCM, ETH_RXBUFNB * sizeof(ETH_DMADescTypeDef)); //申请内存
  176. DMATxDscrTab = mymalloc(SRAMDTCM, ETH_TXBUFNB * sizeof(ETH_DMADescTypeDef)); //申请内存
  177. Rx_Buff = mymalloc(SRAMDTCM, ETH_RX_BUF_SIZE * ETH_RXBUFNB); //申请内存
  178. Tx_Buff = mymalloc(SRAMDTCM, ETH_TX_BUF_SIZE * ETH_TXBUFNB); //申请内存
  179. if (!(u32)&DMARxDscrTab || !(u32)&DMATxDscrTab || !(u32)&Rx_Buff || !(u32)&Tx_Buff)
  180. {
  181. ETH_Mem_Free();
  182. return 1; //申请失败
  183. }
  184. return 0; //申请成功
  185. }
  186. //释放ETH 底层驱动申请的内存
  187. void ETH_Mem_Free(void)
  188. {
  189. myfree(SRAMDTCM, DMARxDscrTab); //释放内存
  190. myfree(SRAMDTCM, DMATxDscrTab); //释放内存
  191. myfree(SRAMDTCM, Rx_Buff); //释放内存
  192. myfree(SRAMDTCM, Tx_Buff); //释放内存
  193. }