stm32f4x7_eth_bsp.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4x7_eth_bsp.c
  4. * @author MCD Application Team
  5. * @version V1.1.0
  6. * @date 31-July-2013
  7. * @brief STM32F4x7 Ethernet hardware configuration.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
  12. *
  13. * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  14. * You may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at:
  16. *
  17. * http://www.st.com/software_license_agreement_liberty_v2
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *
  25. ******************************************************************************
  26. */
  27. /* Includes ------------------------------------------------------------------*/
  28. #include "lwip/opt.h"
  29. #include "stm32f4x7_eth.h"
  30. #include "stm32f4x7_eth_bsp.h"
  31. #include "main_lwip.h"
  32. #include "netif.h"
  33. #include "netconf.h"
  34. #include "lwip/dhcp.h"
  35. //#include "param.h" /* 需要使用存储在 EEPROM中的网络参数 */
  36. /* Private typedef -----------------------------------------------------------*/
  37. /* Private define ------------------------------------------------------------*/
  38. /* Private macro -------------------------------------------------------------*/
  39. /* Private variables ---------------------------------------------------------*/
  40. ETH_InitTypeDef ETH_InitStructure;
  41. __IO uint32_t EthStatus = 0;
  42. extern struct netif gnetif;
  43. #ifdef USE_DHCP
  44. extern __IO uint8_t DHCP_state;
  45. #endif /* LWIP_DHCP */
  46. /* Private function prototypes -----------------------------------------------*/
  47. // static void ETH_GPIO_Config(void);
  48. static void ETH_GPIO_Config_RMII(void);
  49. static void ETH_MACDMA_Config(void);
  50. extern void bsp_DelayMS(uint32_t n);
  51. /* Private functions ---------------------------------------------------------*/
  52. /**
  53. * @brief Inserts a delay time.
  54. * @param nCount: number of 10ms periods to wait for.
  55. * @retval None
  56. */
  57. void ETH_Delay10ms(uint32_t nCount)
  58. {
  59. #if 1
  60. bsp_DelayMS(nCount * 10);
  61. #else
  62. bsp_GetRunTime() / 10
  63. /* Capture the current local time */
  64. timingdelay = bsp_GetRunTime() / 10 + nCount;
  65. /* wait until the desired delay finish */
  66. while (timingdelay > LocalTime)
  67. {
  68. ;
  69. }
  70. #endif
  71. }
  72. /**
  73. * @brief ETH_BSP_Config
  74. * @param None
  75. * @retval None
  76. */
  77. void ETH_BSP_Config(void)
  78. {
  79. #if 0 /* armfly : 我们在 bsp_timer.c 文件配置 systick 中断 */
  80. RCC_ClocksTypeDef RCC_Clocks;
  81. /***************************************************************************
  82. NOTE:
  83. When using Systick to manage the delay in Ethernet driver, the Systick
  84. must be configured before Ethernet initialization and, the interrupt
  85. priority should be the highest one.
  86. *****************************************************************************/
  87. /* Configure Systick clock source as HCLK */
  88. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  89. /* SystTick configuration: an interrupt every 10ms */
  90. RCC_GetClocksFreq(&RCC_Clocks);
  91. SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
  92. /* Set Systick interrupt priority to 0*/
  93. NVIC_SetPriority (SysTick_IRQn, 0);
  94. #endif
  95. /* 打印调试信息 */
  96. lwip_printf("LwIP Enter ETH_BSP_Config()\r\n");
  97. /* Configure the GPIO ports for ethernet pins */
  98. // ETH_GPIO_Config();
  99. ETH_GPIO_Config_RMII();
  100. /* Configure the Ethernet MAC/DMA */
  101. ETH_MACDMA_Config();
  102. /* Read PHY status register: Get Ethernet link status */
  103. if (ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR) & 1)
  104. {
  105. EthStatus |= ETH_LINK_FLAG;
  106. }
  107. /* Configure the PHY to generate an interrupt on change of link status */
  108. Eth_Link_PHYITConfig(DP83848_PHY_ADDRESS);
  109. /* Configure the EXTI for Ethernet link status. */
  110. Eth_Link_EXTIConfig();
  111. }
  112. /**
  113. * @brief Configures the Ethernet Interface
  114. * @param None
  115. * @retval None
  116. */
  117. static void ETH_MACDMA_Config(void)
  118. {
  119. /* 打印调试信息 */
  120. lwip_printf("LwIP Enter ETH_MACDMA_Config()\r\n");
  121. /* Enable ETHERNET clock */
  122. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
  123. RCC_AHB1Periph_ETH_MAC_Rx,
  124. ENABLE);
  125. /* Reset ETHERNET on AHB Bus */
  126. ETH_DeInit();
  127. /* Software reset */
  128. ETH_SoftwareReset();
  129. /* Wait for software reset */
  130. while (ETH_GetSoftwareResetStatus() == SET)
  131. ;
  132. /* ETHERNET Configuration --------------------------------------------------*/
  133. /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
  134. ETH_StructInit(&ETH_InitStructure);
  135. /* Fill ETH_InitStructure parametrs */
  136. /*------------------------ MAC -----------------------------------*/
  137. ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
  138. // ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
  139. // ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  140. // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
  141. ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
  142. ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
  143. ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
  144. ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
  145. ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
  146. ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
  147. ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
  148. ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
  149. #ifdef CHECKSUM_BY_HARDWARE
  150. ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
  151. #endif
  152. /*------------------------ DMA -----------------------------------------*/
  153. /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
  154. the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
  155. if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  156. ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
  157. ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
  158. ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
  159. ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
  160. ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
  161. ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
  162. ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
  163. ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
  164. ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
  165. ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
  166. ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
  167. /* 打印调试信息 */
  168. lwip_printf("LwIP Enter ETH_Init()\r\n");
  169. /* Configure Ethernet */
  170. EthStatus = ETH_Init(&ETH_InitStructure, DP83848_PHY_ADDRESS);
  171. }
  172. /**
  173. * @brief Configures the different GPIO ports.
  174. * @param None
  175. * @retval None
  176. */
  177. static void ETH_GPIO_Config_RMII(void)
  178. {
  179. GPIO_InitTypeDef GPIO_InitStructure;
  180. /* 安富莱STM32-F4开发板网卡接口采用RMII
  181. PA1/ETH_RMII_RX_CLK
  182. PA2/ETH_MDIO
  183. PA7/RMII_CRS_DV
  184. PC1/ETH_MDC
  185. PC4/ETH_RMII_RX_D0
  186. PC5/ETH_RMII_RX_D1
  187. PG11/ETH_RMII_TX_EN
  188. PG13/FSMC_A24/ETH_RMII_TXD0
  189. PG14/ETH_RMII_TXD1
  190. PH6/MII_INT
  191. */
  192. /* Enable GPIOs clocks */
  193. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG |
  194. RCC_AHB1Periph_GPIOH,
  195. ENABLE);
  196. /* Enable SYSCFG clock */
  197. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  198. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
  199. /* Configure PA1, PA2 and PA7 */
  200. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  201. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  202. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  203. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  204. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7;
  205. GPIO_Init(GPIOA, &GPIO_InitStructure);
  206. GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
  207. GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
  208. GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
  209. /* Configure PC1, PC4 and PC5 */
  210. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
  211. GPIO_Init(GPIOC, &GPIO_InitStructure);
  212. GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
  213. GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
  214. GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
  215. /* Configure PG11, PG14 and PG13 */
  216. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14;
  217. GPIO_Init(GPIOG, &GPIO_InitStructure);
  218. GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
  219. GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
  220. GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
  221. }
  222. /**
  223. * @brief Configures the different GPIO ports.
  224. * @param None
  225. * @retval None
  226. */
  227. void ETH_GPIO_Config_MII(void) /* armfly : 更名备份 */
  228. {
  229. GPIO_InitTypeDef GPIO_InitStructure;
  230. /* Enable GPIOs clocks */
  231. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
  232. RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOI |
  233. RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH |
  234. RCC_AHB1Periph_GPIOF,
  235. ENABLE);
  236. /* Enable SYSCFG clock */
  237. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  238. /* Configure MCO (PA8) */
  239. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  240. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  241. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  242. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  243. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  244. GPIO_Init(GPIOA, &GPIO_InitStructure);
  245. /* MII/RMII Media interface selection --------------------------------------*/
  246. #ifdef MII_MODE /* Mode MII with STM324xx-EVAL */
  247. #ifdef PHY_CLOCK_MCO
  248. /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */
  249. RCC_MCO1Config(RCC_MCO1Source_HSE, RCC_MCO1Div_1);
  250. #endif /* PHY_CLOCK_MCO */
  251. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_MII);
  252. #elif defined RMII_MODE /* Mode RMII with STM324xx-EVAL */
  253. SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
  254. #endif
  255. /* Ethernet pins configuration ************************************************/
  256. /*
  257. ETH_MDIO -------------------------> PA2
  258. ETH_MDC --------------------------> PC1
  259. ETH_PPS_OUT ----------------------> PB5
  260. ETH_MII_CRS ----------------------> PH2
  261. ETH_MII_COL ----------------------> PH3
  262. ETH_MII_RX_ER --------------------> PI10
  263. ETH_MII_RXD2 ---------------------> PH6
  264. ETH_MII_RXD3 ---------------------> PH7
  265. ETH_MII_TX_CLK -------------------> PC3
  266. ETH_MII_TXD2 ---------------------> PC2
  267. ETH_MII_TXD3 ---------------------> PB8
  268. ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
  269. ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
  270. ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
  271. ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
  272. ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11
  273. ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13
  274. ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14
  275. */
  276. /* Configure PA1, PA2 and PA7 */
  277. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7;
  278. GPIO_Init(GPIOA, &GPIO_InitStructure);
  279. GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
  280. GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
  281. GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
  282. /* Configure PB5 and PB8 */
  283. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8;
  284. GPIO_Init(GPIOB, &GPIO_InitStructure);
  285. GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_ETH);
  286. GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_ETH);
  287. /* Configure PC1, PC2, PC3, PC4 and PC5 */
  288. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
  289. GPIO_Init(GPIOC, &GPIO_InitStructure);
  290. GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
  291. GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_ETH);
  292. GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_ETH);
  293. GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
  294. GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
  295. /* Configure PG11, PG14 and PG13 */
  296. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14;
  297. GPIO_Init(GPIOG, &GPIO_InitStructure);
  298. GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
  299. GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
  300. GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
  301. /* Configure PH2, PH3, PH6, PH7 */
  302. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;
  303. GPIO_Init(GPIOH, &GPIO_InitStructure);
  304. GPIO_PinAFConfig(GPIOH, GPIO_PinSource2, GPIO_AF_ETH);
  305. GPIO_PinAFConfig(GPIOH, GPIO_PinSource3, GPIO_AF_ETH);
  306. GPIO_PinAFConfig(GPIOH, GPIO_PinSource6, GPIO_AF_ETH);
  307. GPIO_PinAFConfig(GPIOH, GPIO_PinSource7, GPIO_AF_ETH);
  308. /* Configure PI10 */
  309. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  310. GPIO_Init(GPIOI, &GPIO_InitStructure);
  311. GPIO_PinAFConfig(GPIOI, GPIO_PinSource10, GPIO_AF_ETH);
  312. }
  313. /**
  314. * @brief Configure the PHY to generate an interrupt on change of link status.
  315. * @param PHYAddress: external PHY address
  316. * @retval None
  317. */
  318. uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress)
  319. {
  320. uint16_t tmpreg = 0;
  321. /* Read MICR register */
  322. tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MICR);
  323. /* Enable output interrupt events to signal via the INT pin */
  324. tmpreg |= (uint16_t)(PHY_MICR_INT_EN | PHY_MICR_INT_OE);
  325. if (!(ETH_WritePHYRegister(PHYAddress, PHY_MICR, tmpreg)))
  326. {
  327. /* Return ERROR in case of write timeout */
  328. return ETH_ERROR;
  329. }
  330. /* Read MISR register */
  331. tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MISR);
  332. /* Enable Interrupt on change of link status */
  333. tmpreg |= (uint16_t)PHY_MISR_LINK_INT_EN;
  334. if (!(ETH_WritePHYRegister(PHYAddress, PHY_MISR, tmpreg)))
  335. {
  336. /* Return ERROR in case of write timeout */
  337. return ETH_ERROR;
  338. }
  339. /* Return SUCCESS */
  340. return ETH_SUCCESS;
  341. }
  342. /**
  343. * @brief EXTI configuration for Ethernet link status.
  344. * @param PHYAddress: external PHY address
  345. * @retval None
  346. */
  347. void Eth_Link_EXTIConfig(void)
  348. {
  349. GPIO_InitTypeDef GPIO_InitStructure;
  350. EXTI_InitTypeDef EXTI_InitStructure;
  351. NVIC_InitTypeDef NVIC_InitStructure;
  352. /* Enable the INT (PB14) Clock */
  353. RCC_AHB1PeriphClockCmd(ETH_LINK_GPIO_CLK, ENABLE);
  354. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  355. /* Configure INT pin as input */
  356. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  357. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  358. GPIO_InitStructure.GPIO_Pin = ETH_LINK_PIN;
  359. GPIO_Init(ETH_LINK_GPIO_PORT, &GPIO_InitStructure);
  360. /* Connect EXTI Line to INT Pin */
  361. SYSCFG_EXTILineConfig(ETH_LINK_EXTI_PORT_SOURCE, ETH_LINK_EXTI_PIN_SOURCE);
  362. /* Configure EXTI line */
  363. EXTI_InitStructure.EXTI_Line = ETH_LINK_EXTI_LINE;
  364. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  365. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  366. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  367. EXTI_Init(&EXTI_InitStructure);
  368. /* Enable and set the EXTI interrupt to priority 1*/
  369. NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  370. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  371. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  372. NVIC_Init(&NVIC_InitStructure);
  373. }
  374. /**
  375. * @brief This function handles Ethernet link status.
  376. * @param None
  377. * @retval None
  378. */
  379. void Eth_Link_ITHandler(uint16_t PHYAddress)
  380. {
  381. /* Check whether the link interrupt has occurred or not */
  382. if (((ETH_ReadPHYRegister(PHYAddress, PHY_MISR)) & PHY_LINK_STATUS) != 0)
  383. {
  384. if ((ETH_ReadPHYRegister(PHYAddress, PHY_SR) & 1))
  385. {
  386. netif_set_link_up(&gnetif);
  387. }
  388. else
  389. {
  390. netif_set_link_down(&gnetif);
  391. }
  392. }
  393. }
  394. /**
  395. * @brief Link callback function, this function is called on change of link status.
  396. * @param The network interface
  397. * @retval None
  398. */
  399. void ETH_link_callback(struct netif *netif)
  400. {
  401. __IO uint32_t timeout = 0;
  402. uint32_t tmpreg;
  403. uint16_t RegValue;
  404. struct ip4_addr ipaddr;
  405. struct ip4_addr netmask;
  406. struct ip4_addr gw;
  407. if (netif_is_link_up(netif))
  408. {
  409. /* Restart the auto-negotiation */
  410. if (ETH_InitStructure.ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
  411. {
  412. /* Reset Timeout counter */
  413. timeout = 0;
  414. /* Enable auto-negotiation */
  415. ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_BCR, PHY_AutoNegotiation);
  416. /* Wait until the auto-negotiation will be completed */
  417. do
  418. {
  419. timeout++;
  420. } while (!(ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
  421. /* Reset Timeout counter */
  422. timeout = 0;
  423. /* Read the result of the auto-negotiation */
  424. RegValue = ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_SR);
  425. /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
  426. if ((RegValue & PHY_DUPLEX_STATUS) != (uint16_t)RESET)
  427. {
  428. /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
  429. ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
  430. }
  431. else
  432. {
  433. /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
  434. ETH_InitStructure.ETH_Mode = ETH_Mode_HalfDuplex;
  435. }
  436. /* Configure the MAC with the speed fixed by the auto-negotiation process */
  437. if (RegValue & PHY_SPEED_STATUS)
  438. {
  439. /* Set Ethernet speed to 10M following the auto-negotiation */
  440. ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
  441. }
  442. else
  443. {
  444. /* Set Ethernet speed to 100M following the auto-negotiation */
  445. ETH_InitStructure.ETH_Speed = ETH_Speed_100M;
  446. }
  447. /*------------------------ ETHERNET MACCR Re-Configuration --------------------*/
  448. /* Get the ETHERNET MACCR value */
  449. tmpreg = ETH->MACCR;
  450. /* Set the FES bit according to ETH_Speed value */
  451. /* Set the DM bit according to ETH_Mode value */
  452. tmpreg |= (uint32_t)(ETH_InitStructure.ETH_Speed | ETH_InitStructure.ETH_Mode);
  453. /* Write to ETHERNET MACCR */
  454. ETH->MACCR = (uint32_t)tmpreg;
  455. _eth_delay_(ETH_REG_WRITE_DELAY);
  456. tmpreg = ETH->MACCR;
  457. ETH->MACCR = tmpreg;
  458. }
  459. /* Restart MAC interface */
  460. ETH_Start();
  461. #ifdef USE_DHCP
  462. ipaddr.addr = 0;
  463. netmask.addr = 0;
  464. gw.addr = 0;
  465. DHCP_state = DHCP_START;
  466. #else
  467. IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
  468. IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
  469. IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
  470. #endif /* USE_DHCP */
  471. netif_set_addr(&gnetif, &ipaddr, &netmask, &gw);
  472. /* When the netif is fully configured this function must be called.*/
  473. netif_set_up(&gnetif);
  474. /* 打印调试信息 */
  475. lwip_printf("LwIP Network Cable is now connected \r\n");
  476. #ifndef USE_DHCP
  477. /* Display static IP address */
  478. lwip_printf("LwIP Static IP address = %d.%d.%d.%d \r\n", IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
  479. #endif /* USE_DHCP */
  480. }
  481. else
  482. {
  483. ETH_Stop();
  484. #ifdef USE_DHCP
  485. DHCP_state = DHCP_LINK_DOWN;
  486. dhcp_stop(netif);
  487. #endif /* USE_DHCP */
  488. /* When the netif link is down this function must be called.*/
  489. netif_set_down(&gnetif);
  490. /* 打印调试信息 */
  491. lwip_printf("LwIP Network Cable is unplugged \r\n");
  492. }
  493. }
  494. /**
  495. * @brief PHY外部中断服务程序
  496. * @param 无
  497. * @retval 无
  498. */
  499. void EXTI15_10_IRQHandler(void)
  500. {
  501. if (EXTI_GetITStatus(ETH_LINK_EXTI_LINE) != RESET)
  502. {
  503. Eth_Link_ITHandler(DP83848_PHY_ADDRESS);
  504. /* Clear interrupt pending bit */
  505. EXTI_ClearITPendingBit(ETH_LINK_EXTI_LINE);
  506. }
  507. }
  508. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/