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>© 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 |
|
28 | /* Includes ------------------------------------------------------------------*/
|
29 | #include "lwip/opt.h"
|
30 | #include "stm32f4x7_eth.h"
|
31 | #include "stm32f4x7_eth_bsp.h"
|
32 | #include "stm32f4x7_eth_conf.h"
|
33 | #include "network_interface.h"
|
34 | #include "lwip/netif.h"
|
35 | #include "netconf.h"
|
36 | #include "lwip/dhcp.h"
|
37 | #include "arch/sys_arch.h"
|
38 |
|
39 | /* Scheduler includes */
|
40 | #include "FreeRTOS.h"
|
41 | #include "task.h"
|
42 | #include "semphr.h"
|
43 |
|
44 | /* Private typedef -----------------------------------------------------------*/
|
45 | /* Private define ------------------------------------------------------------*/
|
46 | /* The time to block waiting for input. */
|
47 | #define ETH_LINK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
|
48 | #define ETH_LINK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
49 | #define emacBLOCK_TIME_WAITING_ETH_LINK_IT ( ( portTickType ) 100 )
|
50 | /* Private macro -------------------------------------------------------------*/
|
51 | /* Private variables ---------------------------------------------------------*/
|
52 | ETH_InitTypeDef ETH_InitStructure;
|
53 | __IO uint32_t EthStatus = 0;
|
54 | extern struct netif xnetif;
|
55 | #ifdef USE_DHCP
|
56 | extern __IO uint8_t DHCP_state;
|
57 | #endif /* LWIP_DHCP */
|
58 | xSemaphoreHandle ETH_link_xSemaphore = NULL;
|
59 |
|
60 | /* Private function prototypes -----------------------------------------------*/
|
61 | static void ETH_GPIO_Config(void);
|
62 | static void ETH_NVIC_Config(void);
|
63 | static void ETH_MACDMA_Config(void);
|
64 |
|
65 | /* Forward declarations ------------------------------------------------------*/
|
66 | //extern void Eth_Link_IT_task( void * pvParameters );
|
67 | extern sys_sem_t s_xSemaphore;
|
68 |
|
69 |
|
70 | /* Private functions ---------------------------------------------------------*/
|
71 |
|
72 | /**
|
73 | * @brief ETH_BSP_Config
|
74 | * @param None
|
75 | * @retval None
|
76 | */
|
77 | void ETH_BSP_Config(void)
|
78 | {
|
79 | /* Configure the GPIO ports for ethernet pins */
|
80 | ETH_GPIO_Config();
|
81 |
|
82 | /* Config NVIC for Ethernet */
|
83 | ETH_NVIC_Config();
|
84 |
|
85 | /* Configure the Ethernet MAC/DMA */
|
86 | ETH_MACDMA_Config();
|
87 |
|
88 | /* Get Ethernet link status*/
|
89 | if(ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_SR) & PHY_LINKED_STATUS)
|
90 | {
|
91 | EthStatus |= ETH_LINK_FLAG;
|
92 | }
|
93 |
|
94 | /* Configure the PHY to generate an interrupt on change of link status */
|
95 | Eth_Link_PHYITConfig(LAN8710A_PHY_ADDRESS);
|
96 |
|
97 | /* Configure the EXTI for Ethernet link status. */
|
98 | Eth_Link_EXTIConfig();
|
99 |
|
100 | if (ETH_link_xSemaphore == NULL)
|
101 | {
|
102 | /* create binary semaphore used for ETH_link handling */
|
103 | vSemaphoreCreateBinary( ETH_link_xSemaphore );
|
104 | }
|
105 |
|
106 | /* create the task that handles the ETH_link */
|
107 | xTaskCreate(Eth_Link_IT_task, (char*) "E_link", ETH_LINK_TASK_STACK_SIZE, (void *)LAN8710A_PHY_ADDRESS,
|
108 | ETH_LINK_TASK_PRIORITY,NULL);
|
109 | }
|
110 |
|
111 | /**
|
112 | * @brief Configures the Ethernet Interface
|
113 | * @param None
|
114 | * @retval None
|
115 | */
|
116 | static void ETH_MACDMA_Config(void)
|
117 | {
|
118 | uint32_t timeout=0;
|
119 | uint8_t sw_reset_ok=0;
|
120 |
|
121 | /* Enable ETHERNET clock */
|
122 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
|
123 | RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);
|
124 |
|
125 | /* Reset ETHERNET on AHB Bus */
|
126 | ETH_DeInit();
|
127 |
|
128 | /* Software reset */
|
129 | ETH_SoftwareReset();
|
130 |
|
131 | /* Wait for software reset */
|
132 | //while (ETH_GetSoftwareResetStatus() == SET); //Bug! Endlessloop bei einem Fehler
|
133 |
|
134 | //Andere Variante:
|
135 | while(sw_reset_ok==0) {
|
136 | if(ETH_GetSoftwareResetStatus() != SET) sw_reset_ok=1; // reset ok
|
137 | timeout++;
|
138 | if(timeout>500000) sw_reset_ok=2; // timeout
|
139 | }
|
140 | // check ob timeout
|
141 | if(sw_reset_ok==2) return; // timeout error
|
142 |
|
143 |
|
144 | /* ETHERNET Configuration --------------------------------------------------*/
|
145 | /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
|
146 | ETH_StructInit(Ð_InitStructure);
|
147 |
|
148 | /* Fill ETH_InitStructure parametrs */
|
149 | /*------------------------ MAC -----------------------------------*/
|
150 | ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;
|
151 | // ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
|
152 | //ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
|
153 | // ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
154 |
|
155 | ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
|
156 | ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
|
157 | ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
|
158 | ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
|
159 | ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
|
160 | ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
|
161 | ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
|
162 | ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
|
163 | #ifdef CHECKSUM_BY_HARDWARE
|
164 | ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
|
165 | #endif
|
166 |
|
167 | /*------------------------ DMA -----------------------------------*/
|
168 |
|
169 | /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
|
170 | the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
|
171 | if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
|
172 | ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
|
173 | ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
|
174 | ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
|
175 |
|
176 | ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
|
177 | ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
|
178 | ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;
|
179 | ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
|
180 | ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;
|
181 | ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;
|
182 | ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;
|
183 | ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
|
184 |
|
185 | PHYID_HI = ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, 2); // 0x0007
|
186 | PHYID_LO = ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, 3); // 0xC0Fx
|
187 | if( (PHYID_HI != 0x0007) || (PHYID_LO != 0xC0f1) ){
|
188 | // no phy no fun -> endless loop
|
189 | while(1);
|
190 | }
|
191 |
|
192 |
|
193 | /* Configure Ethernet */
|
194 | EthStatus = ETH_Init(Ð_InitStructure, LAN8710A_PHY_ADDRESS);
|
195 |
|
196 | /* Enable the Ethernet Rx Interrupt */
|
197 | ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);
|
198 | }
|
199 |
|
200 | /**
|
201 | * @brief Configures the different GPIO ports.
|
202 | * @param None
|
203 | * @retval None
|
204 | */
|
205 | void ETH_GPIO_Config(void)
|
206 | {
|
207 | GPIO_InitTypeDef GPIO_InitStructure;
|
208 |
|
209 | /* Enable GPIOs clocks */
|
210 |
|
211 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
|
212 | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOG, ENABLE);
|
213 |
|
214 | // Select the RMII interface. The STM32F1 manual says that this must
|
215 | // be performed whilst the module is under reset and before enabling
|
216 | // the MAC clocks...
|
217 |
|
218 | SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII);
|
219 | //Notieren: Das musste hier hoch. Sonst läuft der Task-Scheduler nicht.
|
220 | /* Enable SYSCFG clock */
|
221 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
222 |
|
223 |
|
224 | /* Ethernet pins configuration ************************************************/
|
225 | /*
|
226 | * ETH_MDINT-------------------------> PA3
|
227 | ETH_MDIO -------------------------> PA2
|
228 | ETH_MDC --------------------------> PC1
|
229 | ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
|
230 | ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
|
231 | ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
|
232 | ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
|
233 | ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11
|
234 | ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13
|
235 | ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14
|
236 | */
|
237 |
|
238 |
|
239 | // Configure PA1, PA2, PA7
|
240 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7;
|
241 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
242 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
243 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
244 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
245 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
246 | // Connect PA1, PA2, PA3 and PA7 to ethernet module
|
247 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH);
|
248 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
|
249 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_ETH);
|
250 | GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
|
251 |
|
252 | // Configure PC1, PC4, PC5
|
253 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
|
254 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
255 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
256 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
257 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
258 | GPIO_Init(GPIOC, &GPIO_InitStructure);
|
259 | // Connect PC1, PC4 and PC5 to ethernet module
|
260 | GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH);
|
261 | GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
|
262 | GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);
|
263 |
|
264 | // Configure PG11, PG13, PG14
|
265 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14;
|
266 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
267 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
268 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
269 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
270 | GPIO_Init(GPIOG, &GPIO_InitStructure);
|
271 | // Connect PG11, PG13 and PG14 to ethernet module
|
272 | GPIO_PinAFConfig(GPIOG, GPIO_PinSource11, GPIO_AF_ETH);
|
273 | GPIO_PinAFConfig(GPIOG, GPIO_PinSource13, GPIO_AF_ETH);
|
274 | GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_ETH);
|
275 |
|
276 | }
|
277 |
|
278 | /**
|
279 | * @brief Configures and enable the Ethernet global interrupt.
|
280 | * @param None
|
281 | * @retval None
|
282 | */
|
283 | void ETH_NVIC_Config(void)
|
284 | {
|
285 | NVIC_InitTypeDef NVIC_InitStructure;
|
286 |
|
287 | /* Enable the Ethernet global Interrupt */
|
288 | NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
|
289 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 12 ;
|
290 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
291 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
292 | NVIC_Init(&NVIC_InitStructure);
|
293 |
|
294 | }
|
295 |
|
296 | /**
|
297 | * @brief Configure the PHY to generate an interrupt on change of link status.
|
298 | * @param PHYAddress: external PHY address
|
299 | * @retval None
|
300 | */
|
301 | uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress)
|
302 | {
|
303 | uint16_t tmpreg = 0;
|
304 |
|
305 |
|
306 | /* Read Interrupt Flag register */
|
307 | tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MIFR);
|
308 |
|
309 | /* clear ALTINT */
|
310 | tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MCSR);
|
311 | tmpreg &= ~(uint16_t)(PHY_MCSR_ALTINT);
|
312 | if(!(ETH_WritePHYRegister(PHYAddress, PHY_MCSR, tmpreg)))
|
313 | {
|
314 | /* Return ERROR in case of write timeout */
|
315 | return ETH_ERROR;
|
316 | }
|
317 |
|
318 | /* Read Mask register */
|
319 | tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MIMR);
|
320 |
|
321 | /* Enable Interrupt on change of link and energy status */
|
322 | tmpreg |= (uint16_t)(PHY_MIMR_LINK_INT_EN | PHY_MIMR_AUTON_INT_EN);
|
323 | if(!(ETH_WritePHYRegister(PHYAddress, PHY_MIMR, tmpreg)))
|
324 | {
|
325 | /* Return ERROR in case of write timeout */
|
326 | return ETH_ERROR;
|
327 | }
|
328 | /* Return SUCCESS */
|
329 | return ETH_SUCCESS;
|
330 |
|
331 | }
|
332 |
|
333 | /**
|
334 | * @brief EXTI configuration for Ethernet link status.
|
335 | * @param PHYAddress: external PHY address
|
336 | * @retval None
|
337 | */
|
338 | void Eth_Link_EXTIConfig(void)
|
339 | {
|
340 | GPIO_InitTypeDef GPIO_InitStructure;
|
341 | EXTI_InitTypeDef EXTI_InitStructure;
|
342 | NVIC_InitTypeDef NVIC_InitStructure;
|
343 |
|
344 | /* Enable the INT (PA3) Clock */
|
345 | RCC_AHB1PeriphClockCmd(ETH_LINK_GPIO_CLK, ENABLE);
|
346 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
347 |
|
348 | /* Configure INT pin as input */
|
349 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
350 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
351 | GPIO_InitStructure.GPIO_Pin = ETH_LINK_PIN;
|
352 | GPIO_Init(ETH_LINK_GPIO_PORT, &GPIO_InitStructure);
|
353 |
|
354 | /* Connect EXTI Line to INT Pin */
|
355 | SYSCFG_EXTILineConfig(ETH_LINK_EXTI_PORT_SOURCE, ETH_LINK_EXTI_PIN_SOURCE);
|
356 |
|
357 | /* Configure EXTI line */
|
358 | EXTI_InitStructure.EXTI_Line = ETH_LINK_EXTI_LINE;
|
359 | EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
360 | EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
|
361 | EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
362 | EXTI_Init(&EXTI_InitStructure);
|
363 |
|
364 | /* Enable and set the EXTI interrupt to priority 1*/
|
365 | NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
|
366 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13;
|
367 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
368 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
369 | NVIC_Init(&NVIC_InitStructure);
|
370 | }
|
371 |
|
372 | /**
|
373 | * @brief This function handles Ethernet link status.
|
374 | * @param None
|
375 | * @retval None
|
376 | */
|
377 | void Eth_Link_IT_task( void * pvParameters )
|
378 | {
|
379 | for(;;) {
|
380 | // RHB chng: Wait w/o timeout, because Link Up and Down are Signaled by ISR
|
381 | // if (sys_arch_sem_wait( Ð_link_xSemaphore, emacBLOCK_TIME_WAITING_ETH_LINK_IT))
|
382 | sys_arch_sem_wait( Ð_link_xSemaphore, 0);
|
383 |
|
384 | /* Get Ethernet link status*/
|
385 | uint16_t sr = ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_SR);
|
386 | if( sr & PHY_Linked_Status) {
|
387 | /* Set link up */
|
388 | netif_set_link_up(&xnetif);
|
389 | } else {
|
390 | /* Set link down */
|
391 | netif_set_link_down(&xnetif);
|
392 | }
|
393 | }
|
394 | }
|
395 | /**
|
396 | * @brief Link callback function, this function is called on change of link status.
|
397 | * @param The network interface
|
398 | * @retval None
|
399 | */
|
400 | void ETH_link_callback(struct netif *netif)
|
401 | {
|
402 | __IO uint32_t timeout = 0;
|
403 | uint32_t tmpreg,RegValue;
|
404 |
|
405 | struct ip_addr ipaddr;
|
406 | struct ip_addr netmask;
|
407 | struct ip_addr gw;
|
408 | #ifndef USE_DHCP
|
409 | uint8_t iptab[4] = {0};
|
410 | uint8_t iptxt[20];
|
411 | #endif /* USE_DHCP */
|
412 |
|
413 | if(netif_is_link_up(netif))
|
414 | {
|
415 | /* Restart the autonegotiation */
|
416 | if(ETH_InitStructure.ETH_AutoNegotiation != ETH_AutoNegotiation_Disable)
|
417 | {
|
418 | /* Reset Timeout counter */
|
419 | timeout = 0;
|
420 |
|
421 | /* Enable Auto-Negotiation */
|
422 | ETH_WritePHYRegister(LAN8710A_PHY_ADDRESS, PHY_BCR, PHY_AutoNegotiation);
|
423 |
|
424 | /* Wait until the auto-negotiation will be completed */
|
425 | do
|
426 | {
|
427 | timeout++;
|
428 | } while (!(ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_BSR) & PHY_AutoNego_Complete) && (timeout < (uint32_t)PHY_READ_TO));
|
429 |
|
430 | /* Reset Timeout counter */
|
431 | timeout = 0;
|
432 |
|
433 | /* Read the result of the auto-negotiation */
|
434 | RegValue = ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_SR);
|
435 |
|
436 | /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
|
437 | if((RegValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
|
438 | {
|
439 | /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
|
440 | ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
|
441 | }
|
442 | else
|
443 | {
|
444 | /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
|
445 | ETH_InitStructure.ETH_Mode = ETH_Mode_HalfDuplex;
|
446 | }
|
447 | /* Configure the MAC with the speed fixed by the auto-negotiation process */
|
448 | if(RegValue & PHY_SPEED_100)
|
449 | {
|
450 | /* Set Ethernet speed to 100M following the auto-negotiation */
|
451 | ETH_InitStructure.ETH_Speed = ETH_Speed_100M;
|
452 | }
|
453 | else
|
454 | {
|
455 | /* Set Ethernet speed to 10M following the auto-negotiation */
|
456 | ETH_InitStructure.ETH_Speed = ETH_Speed_10M;
|
457 | }
|
458 |
|
459 | /*------------------------ ETHERNET MACCR Re-Configuration --------------------*/
|
460 | /* Get the ETHERNET MACCR value */
|
461 | tmpreg = ETH->MACCR;
|
462 |
|
463 | /* Set the FES bit according to ETH_Speed value */
|
464 | /* Set the DM bit according to ETH_Mode value */
|
465 | tmpreg |= (uint32_t)(ETH_InitStructure.ETH_Speed | ETH_InitStructure.ETH_Mode);
|
466 |
|
467 | /* Write to ETHERNET MACCR */
|
468 | ETH->MACCR = (uint32_t)tmpreg;
|
469 |
|
470 | //Commented out by DN: Why 2 times?
|
471 | _eth_delay_(ETH_REG_WRITE_DELAY);
|
472 | tmpreg = ETH->MACCR;
|
473 | ETH->MACCR = tmpreg;
|
474 | }
|
475 |
|
476 | /* Restart MAC interface */
|
477 | ETH_Start();
|
478 |
|
479 | #ifdef USE_DHCP
|
480 | ipaddr.addr = 0;
|
481 | netmask.addr = 0;
|
482 | gw.addr = 0;
|
483 |
|
484 |
|
485 | DHCP_state = DHCP_START;
|
486 | #else
|
487 | IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
488 | IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
|
489 | IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
|
490 | #endif /* USE_DHCP */
|
491 |
|
492 | netif_set_addr(&xnetif, &ipaddr , &netmask, &gw);
|
493 |
|
494 | /* When the netif is fully configured this function must be called.*/
|
495 | netif_set_up(&xnetif);
|
496 |
|
497 | #ifndef USE_DHCP
|
498 | /* Display static IP address */
|
499 | iptab[0] = IP_ADDR3;
|
500 | iptab[1] = IP_ADDR2;
|
501 | iptab[2] = IP_ADDR1;
|
502 | iptab[3] = IP_ADDR0;
|
503 | #endif
|
504 | }
|
505 | else
|
506 | {
|
507 | ETH_Stop();
|
508 | #ifdef USE_DHCP
|
509 | DHCP_state = DHCP_LINK_DOWN;
|
510 | dhcp_stop(netif);
|
511 |
|
512 | #endif /* USE_DHCP */
|
513 |
|
514 | /* When the netif link is down this function must be called.*/
|
515 | netif_set_down(&xnetif);
|
516 | }
|
517 | }
|
518 |
|
519 | /**
|
520 | * @brief This function handles Ethernet link status.
|
521 | * @param None
|
522 | * @retval None
|
523 | */
|
524 |
|
525 | void EXTI3_IRQHandler(void){
|
526 |
|
527 | /* Clear the EXTI line 3 pending bit */
|
528 | EXTI_ClearITPendingBit(EXTI_Line3);
|
529 |
|
530 | uint16_t tmpreg=ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_MIFR);
|
531 |
|
532 | /* Check interrupt source : Autonegotiation Complete Flag acts as link up */
|
533 | /* and link down acts as link down */
|
534 | if(tmpreg & PHY_MIFR_LINK_FLAG) {
|
535 | // Reading the Base status register will clear interrupt flag
|
536 | ETH_ReadPHYRegister(LAN8710A_PHY_ADDRESS, PHY_SR);
|
537 |
|
538 | } else if(tmpreg & PHY_MIFR_AUTON_FLAG) {
|
539 | // Reading the flag register ( done above ) has already cleared the flag bit
|
540 | }
|
541 |
|
542 | /* Give the semaphore to wakeup LwIP task */
|
543 | sys_sem_signal( Ð_link_xSemaphore);
|
544 |
|
545 | }
|
546 |
|
547 | /**
|
548 | * @brief This function handles ethernet DMA interrupt request.
|
549 | * @param None
|
550 | * @retval None
|
551 | */
|
552 | void ETH_IRQHandler(void)
|
553 | {
|
554 |
|
555 | /* Frame received */
|
556 | if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET) {
|
557 | /* Clear the interrupt flags. */
|
558 | /* Clear the Eth DMA Rx IT pending bits */
|
559 | ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
560 | ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
|
561 | /* Give the semaphore to wakeup LwIP task */
|
562 | sys_sem_signal( &s_xSemaphore);
|
563 | }
|
564 |
|
565 | if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_NIS) == SET) {
|
566 | ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);
|
567 | }
|
568 |
|
569 | }
|
570 |
|
571 |
|
572 |
|
573 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|