stm32f7xx_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file stm32f7xx_eth_driver.c
3  * @brief STM32F7 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "stm32f7xx.h"
36 #include "stm32f7xx_hal.h"
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //IAR EWARM compiler?
45 #if defined(__ICCARM__)
46 
47 //Transmit buffer
48 #pragma data_alignment = 4
49 #pragma location = ".ram_no_cache"
51 //Receive buffer
52 #pragma data_alignment = 4
53 #pragma location = ".ram_no_cache"
55 //Transmit DMA descriptors
56 #pragma data_alignment = 4
57 #pragma location = ".ram_no_cache"
59 //Receive DMA descriptors
60 #pragma data_alignment = 4
61 #pragma location = ".ram_no_cache"
63 
64 //Keil MDK-ARM or GCC compiler?
65 #else
66 
67 //Transmit buffer
69  __attribute__((aligned(4), __section__(".ram_no_cache")));
70 //Receive buffer
72  __attribute__((aligned(4), __section__(".ram_no_cache")));
73 //Transmit DMA descriptors
75  __attribute__((aligned(4), __section__(".ram_no_cache")));
76 //Receive DMA descriptors
78  __attribute__((aligned(4), __section__(".ram_no_cache")));
79 
80 #endif
81 
82 //Pointer to the current TX DMA descriptor
83 static Stm32f7xxTxDmaDesc *txCurDmaDesc;
84 //Pointer to the current RX DMA descriptor
85 static Stm32f7xxRxDmaDesc *rxCurDmaDesc;
86 
87 
88 /**
89  * @brief STM32F7 Ethernet MAC driver
90  **/
91 
93 {
95  ETH_MTU,
106  TRUE,
107  TRUE,
108  TRUE,
109  FALSE
110 };
111 
112 
113 /**
114  * @brief STM32F7 Ethernet MAC initialization
115  * @param[in] interface Underlying network interface
116  * @return Error code
117  **/
118 
120 {
121  error_t error;
122 
123  //Debug message
124  TRACE_INFO("Initializing STM32F7 Ethernet MAC...\r\n");
125 
126  //Save underlying network interface
127  nicDriverInterface = interface;
128 
129  //GPIO configuration
130  stm32f7xxEthInitGpio(interface);
131 
132  //Enable Ethernet MAC clock
133  __HAL_RCC_ETHMAC_CLK_ENABLE();
134  __HAL_RCC_ETHMACTX_CLK_ENABLE();
135  __HAL_RCC_ETHMACRX_CLK_ENABLE();
136 
137  //Reset Ethernet MAC peripheral
138  __HAL_RCC_ETHMAC_FORCE_RESET();
139  __HAL_RCC_ETHMAC_RELEASE_RESET();
140 
141  //Perform a software reset
142  ETH->DMABMR |= ETH_DMABMR_SR;
143  //Wait for the reset to complete
144  while(ETH->DMABMR & ETH_DMABMR_SR)
145  {
146  }
147 
148  //Adjust MDC clock range depending on HCLK frequency
149  ETH->MACMIIAR = ETH_MACMIIAR_CR_Div102;
150 
151  //PHY transceiver initialization
152  error = interface->phyDriver->init(interface);
153  //Failed to initialize PHY transceiver?
154  if(error)
155  return error;
156 
157  //Use default MAC configuration
158  ETH->MACCR = ETH_MACCR_ROD;
159 
160  //Set the MAC address of the station
161  ETH->MACA0LR = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
162  ETH->MACA0HR = interface->macAddr.w[2];
163 
164  //The MAC supports 3 additional addresses for unicast perfect filtering
165  ETH->MACA1LR = 0;
166  ETH->MACA1HR = 0;
167  ETH->MACA2LR = 0;
168  ETH->MACA2HR = 0;
169  ETH->MACA3LR = 0;
170  ETH->MACA3HR = 0;
171 
172  //Initialize hash table
173  ETH->MACHTLR = 0;
174  ETH->MACHTHR = 0;
175 
176  //Configure the receive filter
177  ETH->MACFFR = ETH_MACFFR_HPF | ETH_MACFFR_HM;
178  //Disable flow control
179  ETH->MACFCR = 0;
180  //Enable store and forward mode
181  ETH->DMAOMR = ETH_DMAOMR_RSF | ETH_DMAOMR_TSF;
182 
183  //Configure DMA bus mode
184  ETH->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_USP | ETH_DMABMR_RDP_1Beat |
185  ETH_DMABMR_RTPR_1_1 | ETH_DMABMR_PBL_1Beat | ETH_DMABMR_EDE;
186 
187  //Initialize DMA descriptor lists
188  stm32f7xxEthInitDmaDesc(interface);
189 
190  //Prevent interrupts from being generated when the transmit statistic
191  //counters reach half their maximum value
192  ETH->MMCTIMR = ETH_MMCTIMR_TGFM | ETH_MMCTIMR_TGFMSCM | ETH_MMCTIMR_TGFSCM;
193 
194  //Prevent interrupts from being generated when the receive statistic
195  //counters reach half their maximum value
196  ETH->MMCRIMR = ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RFCEM;
197 
198  //Disable MAC interrupts
199  ETH->MACIMR = ETH_MACIMR_TSTIM | ETH_MACIMR_PMTIM;
200  //Enable the desired DMA interrupts
201  ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE;
202 
203  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
204  NVIC_SetPriorityGrouping(STM32F7XX_ETH_IRQ_PRIORITY_GROUPING);
205 
206  //Configure Ethernet interrupt priority
207  NVIC_SetPriority(ETH_IRQn, NVIC_EncodePriority(STM32F7XX_ETH_IRQ_PRIORITY_GROUPING,
209 
210  //Enable MAC transmission and reception
211  ETH->MACCR |= ETH_MACCR_TE | ETH_MACCR_RE;
212  //Enable DMA transmission and reception
213  ETH->DMAOMR |= ETH_DMAOMR_ST | ETH_DMAOMR_SR;
214 
215  //Accept any packets from the upper layer
216  osSetEvent(&interface->nicTxEvent);
217 
218  //Successful initialization
219  return NO_ERROR;
220 }
221 
222 
223 //STM32756G-EVAL, STM32F769I-EVAL, STM32F746G-Discovery, STM32F7508-Discovery,
224 //STM32F769I-Discovery, Nucleo-F746ZG or Nucleo-F767ZI evaluation board?
225 #if defined(USE_STM32756G_EVAL) || defined(USE_STM32F769I_EVAL) || \
226  defined(USE_STM32746G_DISCO) || defined(USE_STM32F7508_DISCO) || \
227  defined(USE_STM32F769I_DISCO) ||defined(USE_STM32F7XX_NUCLEO_144)
228 
229 /**
230  * @brief GPIO configuration
231  * @param[in] interface Underlying network interface
232  **/
233 
234 void stm32f7xxEthInitGpio(NetInterface *interface)
235 {
236  GPIO_InitTypeDef GPIO_InitStructure;
237 
238 //STM32756G-EVAL or STM32F769I-EVAL evaluation board?
239 #if defined(USE_STM32756G_EVAL) || defined(USE_STM32F769I_EVAL)
240  //Enable SYSCFG clock
241  __HAL_RCC_SYSCFG_CLK_ENABLE();
242 
243  //Enable GPIO clocks
244  __HAL_RCC_GPIOA_CLK_ENABLE();
245  __HAL_RCC_GPIOC_CLK_ENABLE();
246  __HAL_RCC_GPIOE_CLK_ENABLE();
247  __HAL_RCC_GPIOG_CLK_ENABLE();
248  __HAL_RCC_GPIOH_CLK_ENABLE();
249  __HAL_RCC_GPIOI_CLK_ENABLE();
250 
251  //Configure MCO1 (PA8) as an output
252  GPIO_InitStructure.Pin = GPIO_PIN_8;
253  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
254  GPIO_InitStructure.Pull = GPIO_NOPULL;
255  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
256  GPIO_InitStructure.Alternate = GPIO_AF0_MCO;
257  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
258 
259  //Configure MCO1 pin to output the HSE clock (25MHz)
260  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1);
261 
262  //Select MII interface mode
263  SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL;
264 
265 #if defined(STM32F7XX_ETH_MDIO_PIN) && defined(STM32F7XX_ETH_MDC_PIN)
266  //Configure ETH_MDIO as a GPIO
267  GPIO_InitStructure.Pin = STM32F7XX_ETH_MDIO_PIN;
268  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
269  GPIO_InitStructure.Pull = GPIO_PULLUP;
270  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
271  HAL_GPIO_Init(STM32F7XX_ETH_MDIO_GPIO, &GPIO_InitStructure);
272 
273  //Configure ETH_MDC as a GPIO
274  GPIO_InitStructure.Pin = STM32F7XX_ETH_MDC_PIN;
275  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
276  GPIO_InitStructure.Pull = GPIO_NOPULL;
277  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
278  HAL_GPIO_Init(STM32F7XX_ETH_MDC_GPIO, &GPIO_InitStructure);
279 
280  //Deassert MDC
281  HAL_GPIO_WritePin(STM32F7XX_ETH_MDC_GPIO,
282  STM32F7XX_ETH_MDC_PIN, GPIO_PIN_RESET);
283 #else
284  //Configure ETH_MDIO (PA2)
285  GPIO_InitStructure.Pin = GPIO_PIN_2;
286  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
287  GPIO_InitStructure.Pull = GPIO_PULLUP;
288  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
289  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
290  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
291 
292  //Configure ETH_MDC (PC1)
293  GPIO_InitStructure.Pin = GPIO_PIN_1;
294  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
295  GPIO_InitStructure.Pull = GPIO_NOPULL;
296  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
297  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
298  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
299 #endif
300 
301  //Configure MII pins
302  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
303  GPIO_InitStructure.Pull = GPIO_NOPULL;
304  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
305  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
306 
307  //Configure ETH_MII_CRS (PA0)
308  //GPIO_InitStructure.Pin = GPIO_PIN_0;
309  //HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
310 
311  //Configure ETH_MII_RX_CLK (PA1) and ETH_MII_RX_DV (PA7)
312  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_7;
313  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
314 
315  //Configure ETH_MII_TXD2 (PC2), ETH_MII_TX_CLK (PC3), ETH_MII_RXD0 (PC4)
316  //and ETH_MII_RXD1 (PC5)
317  GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
318  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
319 
320  //Configure ETH_MII_TXD3 (PE2)
321  GPIO_InitStructure.Pin = GPIO_PIN_2;
322  HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
323 
324  //Configure ETH_MII_TX_EN (PG11), ETH_MII_TXD0 (PG13) and ETH_MII_TXD1 (PG14)
325  GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
326  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
327 
328  //Configure ETH_MII_COL (PH3)
329  //GPIO_InitStructure.Pin = GPIO_PIN_3;
330  //HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
331 
332  //Configure ETH_MII_RXD2 (PH6) and ETH_MII_RXD3 (PH7)
333  GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
334  HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
335 
336  //Configure ETH_MII_RX_ER (PI10)
337  //GPIO_InitStructure.Pin = GPIO_PIN_10;
338  //HAL_GPIO_Init(GPIOI, &GPIO_InitStructure);
339 
340 //STM32F746G-Discovery or STM32F7508-Discovery evaluation board?
341 #elif defined(USE_STM32746G_DISCO) || defined(USE_STM32F7508_DISCO)
342  //Enable SYSCFG clock
343  __HAL_RCC_SYSCFG_CLK_ENABLE();
344 
345  //Enable GPIO clocks
346  __HAL_RCC_GPIOA_CLK_ENABLE();
347  __HAL_RCC_GPIOC_CLK_ENABLE();
348  __HAL_RCC_GPIOG_CLK_ENABLE();
349 
350  //Select RMII interface mode
351  SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
352 
353  //Configure RMII pins
354  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
355  GPIO_InitStructure.Pull = GPIO_NOPULL;
356  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
357  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
358 
359  //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7)
360  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
361  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
362 
363  //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5)
364  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
365  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
366 
367  //Configure ETH_RMII_RX_ER (PG2), ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13)
368  //and ETH_RMII_TXD1 (PG14)
369  GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
370  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
371 
372 //STM32F769I-Discovery evaluation board?
373 #elif defined(USE_STM32F769I_DISCO)
374  //Enable SYSCFG clock
375  __HAL_RCC_SYSCFG_CLK_ENABLE();
376 
377  //Enable GPIO clocks
378  __HAL_RCC_GPIOA_CLK_ENABLE();
379  __HAL_RCC_GPIOC_CLK_ENABLE();
380  __HAL_RCC_GPIOD_CLK_ENABLE();
381  __HAL_RCC_GPIOG_CLK_ENABLE();
382 
383  //Select RMII interface mode
384  SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
385 
386  //Configure RMII pins
387  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
388  GPIO_InitStructure.Pull = GPIO_NOPULL;
389  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
390  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
391 
392  //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7)
393  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
394  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
395 
396  //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5)
397  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
398  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
399 
400  //Configure ETH_RMII_RX_ER (PD5)
401  GPIO_InitStructure.Pin = GPIO_PIN_5;
402  HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
403 
404  //Configure ETH_RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13) and ETH_RMII_TXD1 (PG14)
405  GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
406  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
407 
408 //Nucleo-F746ZG or Nucleo-F767ZI evaluation board?
409 #elif defined(USE_STM32F7XX_NUCLEO_144)
410  //Enable SYSCFG clock
411  __HAL_RCC_SYSCFG_CLK_ENABLE();
412 
413  //Enable GPIO clocks
414  __HAL_RCC_GPIOA_CLK_ENABLE();
415  __HAL_RCC_GPIOB_CLK_ENABLE();
416  __HAL_RCC_GPIOC_CLK_ENABLE();
417  __HAL_RCC_GPIOG_CLK_ENABLE();
418 
419  //Select RMII interface mode
420  SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
421 
422  //Configure RMII pins
423  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
424  GPIO_InitStructure.Pull = GPIO_NOPULL;
425  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
426  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
427 
428  //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7)
429  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
430  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
431 
432  //Configure ETH_RMII_TXD1 (PB13)
433  GPIO_InitStructure.Pin = GPIO_PIN_13;
434  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
435 
436  //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5)
437  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
438  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
439 
440  //Configure RMII_TX_EN (PG11) and ETH_RMII_TXD0 (PG13)
441  GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13;
442  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
443 #endif
444 }
445 
446 #endif
447 
448 
449 /**
450  * @brief Initialize DMA descriptor lists
451  * @param[in] interface Underlying network interface
452  **/
453 
455 {
456  uint_t i;
457 
458  //Initialize TX DMA descriptor list
459  for(i = 0; i < STM32F7XX_ETH_TX_BUFFER_COUNT; i++)
460  {
461  //Use chain structure rather than ring structure
462  txDmaDesc[i].tdes0 = ETH_TDES0_IC | ETH_TDES0_TCH;
463  //Initialize transmit buffer size
464  txDmaDesc[i].tdes1 = 0;
465  //Transmit buffer address
466  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
467  //Next descriptor address
468  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
469  //Reserved fields
470  txDmaDesc[i].tdes4 = 0;
471  txDmaDesc[i].tdes5 = 0;
472  //Transmit frame time stamp
473  txDmaDesc[i].tdes6 = 0;
474  txDmaDesc[i].tdes7 = 0;
475  }
476 
477  //The last descriptor is chained to the first entry
478  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
479  //Point to the very first descriptor
480  txCurDmaDesc = &txDmaDesc[0];
481 
482  //Initialize RX DMA descriptor list
483  for(i = 0; i < STM32F7XX_ETH_RX_BUFFER_COUNT; i++)
484  {
485  //The descriptor is initially owned by the DMA
486  rxDmaDesc[i].rdes0 = ETH_RDES0_OWN;
487  //Use chain structure rather than ring structure
489  //Receive buffer address
490  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
491  //Next descriptor address
492  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
493  //Extended status
494  rxDmaDesc[i].rdes4 = 0;
495  //Reserved field
496  rxDmaDesc[i].rdes5 = 0;
497  //Receive frame time stamp
498  rxDmaDesc[i].rdes6 = 0;
499  rxDmaDesc[i].rdes7 = 0;
500  }
501 
502  //The last descriptor is chained to the first entry
503  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
504  //Point to the very first descriptor
505  rxCurDmaDesc = &rxDmaDesc[0];
506 
507  //Start location of the TX descriptor list
508  ETH->DMATDLAR = (uint32_t) txDmaDesc;
509  //Start location of the RX descriptor list
510  ETH->DMARDLAR = (uint32_t) rxDmaDesc;
511 }
512 
513 
514 /**
515  * @brief STM32F7 Ethernet MAC timer handler
516  *
517  * This routine is periodically called by the TCP/IP stack to
518  * handle periodic operations such as polling the link state
519  *
520  * @param[in] interface Underlying network interface
521  **/
522 
524 {
525  //Handle periodic operations
526  interface->phyDriver->tick(interface);
527 }
528 
529 
530 /**
531  * @brief Enable interrupts
532  * @param[in] interface Underlying network interface
533  **/
534 
536 {
537  //Enable Ethernet MAC interrupts
538  NVIC_EnableIRQ(ETH_IRQn);
539  //Enable Ethernet PHY interrupts
540  interface->phyDriver->enableIrq(interface);
541 }
542 
543 
544 /**
545  * @brief Disable interrupts
546  * @param[in] interface Underlying network interface
547  **/
548 
550 {
551  //Disable Ethernet MAC interrupts
552  NVIC_DisableIRQ(ETH_IRQn);
553  //Disable Ethernet PHY interrupts
554  interface->phyDriver->disableIrq(interface);
555 }
556 
557 
558 /**
559  * @brief STM32F7 Ethernet MAC interrupt service routine
560  **/
561 
562 void ETH_IRQHandler(void)
563 {
564  bool_t flag;
565  uint32_t status;
566 
567  //Interrupt service routine prologue
568  osEnterIsr();
569 
570  //This flag will be set if a higher priority task must be woken
571  flag = FALSE;
572 
573  //Read DMA status register
574  status = ETH->DMASR;
575 
576  //A packet has been transmitted?
577  if(status & ETH_DMASR_TS)
578  {
579  //Clear TS interrupt flag
580  ETH->DMASR = ETH_DMASR_TS;
581 
582  //Check whether the TX buffer is available for writing
583  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
584  {
585  //Notify the TCP/IP stack that the transmitter is ready to send
586  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
587  }
588  }
589 
590  //A packet has been received?
591  if(status & ETH_DMASR_RS)
592  {
593  //Disable RIE interrupt
594  ETH->DMAIER &= ~ETH_DMAIER_RIE;
595 
596  //Set event flag
597  nicDriverInterface->nicEvent = TRUE;
598  //Notify the TCP/IP stack of the event
599  flag |= osSetEventFromIsr(&netEvent);
600  }
601 
602  //Clear NIS interrupt flag
603  ETH->DMASR = ETH_DMASR_NIS;
604 
605  //Interrupt service routine epilogue
606  osExitIsr(flag);
607 }
608 
609 
610 /**
611  * @brief STM32F7 Ethernet MAC event handler
612  * @param[in] interface Underlying network interface
613  **/
614 
616 {
617  error_t error;
618 
619  //Packet received?
620  if(ETH->DMASR & ETH_DMASR_RS)
621  {
622  //Clear interrupt flag
623  ETH->DMASR = ETH_DMASR_RS;
624 
625  //Process all pending packets
626  do
627  {
628  //Read incoming packet
629  error = stm32f7xxEthReceivePacket(interface);
630 
631  //No more data in the receive buffer?
632  } while(error != ERROR_BUFFER_EMPTY);
633  }
634 
635  //Re-enable DMA interrupts
636  ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE;
637 }
638 
639 
640 /**
641  * @brief Send a packet
642  * @param[in] interface Underlying network interface
643  * @param[in] buffer Multi-part buffer containing the data to send
644  * @param[in] offset Offset to the first data byte
645  * @return Error code
646  **/
647 
649  const NetBuffer *buffer, size_t offset)
650 {
651  static uint8_t temp[STM32F7XX_ETH_TX_BUFFER_SIZE];
652  size_t length;
653 
654  //Retrieve the length of the packet
655  length = netBufferGetLength(buffer) - offset;
656 
657  //Check the frame length
659  {
660  //The transmitter can accept another packet
661  osSetEvent(&interface->nicTxEvent);
662  //Report an error
663  return ERROR_INVALID_LENGTH;
664  }
665 
666  //Make sure the current buffer is available for writing
667  if(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)
668  return ERROR_FAILURE;
669 
670  //Copy user data to the transmit buffer
671  netBufferRead(temp, buffer, offset, length);
672  memcpy((uint8_t *) txCurDmaDesc->tdes2, temp, (length + 3) & ~3UL);
673 
674  //Write the number of bytes to send
675  txCurDmaDesc->tdes1 = length & ETH_TDES1_TBS1;
676  //Set LS and FS flags as the data fits in a single buffer
677  txCurDmaDesc->tdes0 |= ETH_TDES0_LS | ETH_TDES0_FS;
678  //Give the ownership of the descriptor to the DMA
679  txCurDmaDesc->tdes0 |= ETH_TDES0_OWN;
680 
681  //Data synchronization barrier
682  __DSB();
683 
684  //Clear TBUS flag to resume processing
685  ETH->DMASR = ETH_DMASR_TBUS;
686  //Instruct the DMA to poll the transmit descriptor list
687  ETH->DMATPDR = 0;
688 
689  //Point to the next descriptor in the list
690  txCurDmaDesc = (Stm32f7xxTxDmaDesc *) txCurDmaDesc->tdes3;
691 
692  //Check whether the next buffer is available for writing
693  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
694  {
695  //The transmitter can accept another packet
696  osSetEvent(&interface->nicTxEvent);
697  }
698 
699  //Data successfully written
700  return NO_ERROR;
701 }
702 
703 
704 /**
705  * @brief Receive a packet
706  * @param[in] interface Underlying network interface
707  * @return Error code
708  **/
709 
711 {
712  static uint8_t temp[STM32F7XX_ETH_RX_BUFFER_SIZE];
713  error_t error;
714  size_t n;
715 
716  //The current buffer is available for reading?
717  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_OWN))
718  {
719  //FS and LS flags should be set
720  if((rxCurDmaDesc->rdes0 & ETH_RDES0_FS) && (rxCurDmaDesc->rdes0 & ETH_RDES0_LS))
721  {
722  //Make sure no error occurred
723  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_ES))
724  {
725  //Retrieve the length of the frame
726  n = (rxCurDmaDesc->rdes0 & ETH_RDES0_FL) >> 16;
727  //Limit the number of data to read
729 
730  //Copy data from the receive buffer
731  memcpy(temp, (uint8_t *) rxCurDmaDesc->rdes2, (n + 3) & ~3UL);
732 
733  //Pass the packet to the upper layer
734  nicProcessPacket(interface, temp, n);
735 
736  //Valid packet received
737  error = NO_ERROR;
738  }
739  else
740  {
741  //The received packet contains an error
742  error = ERROR_INVALID_PACKET;
743  }
744  }
745  else
746  {
747  //The packet is not valid
748  error = ERROR_INVALID_PACKET;
749  }
750 
751  //Give the ownership of the descriptor back to the DMA
752  rxCurDmaDesc->rdes0 = ETH_RDES0_OWN;
753  //Point to the next descriptor in the list
754  rxCurDmaDesc = (Stm32f7xxRxDmaDesc *) rxCurDmaDesc->rdes3;
755  }
756  else
757  {
758  //No more data in the receive buffer
759  error = ERROR_BUFFER_EMPTY;
760  }
761 
762  //Clear RBUS flag to resume processing
763  ETH->DMASR = ETH_DMASR_RBUS;
764  //Instruct the DMA to poll the receive descriptor list
765  ETH->DMARPDR = 0;
766 
767  //Return status code
768  return error;
769 }
770 
771 
772 /**
773  * @brief Configure MAC address filtering
774  * @param[in] interface Underlying network interface
775  * @return Error code
776  **/
777 
779 {
780  uint_t i;
781  uint_t j;
782  uint_t k;
783  uint32_t crc;
784  uint32_t hashTable[2];
785  MacAddr unicastMacAddr[3];
786  MacFilterEntry *entry;
787 
788  //Debug message
789  TRACE_DEBUG("Updating MAC filter...\r\n");
790 
791  //Set the MAC address of the station
792  ETH->MACA0LR = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
793  ETH->MACA0HR = interface->macAddr.w[2];
794 
795  //The MAC supports 3 additional addresses for unicast perfect filtering
796  unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
797  unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
798  unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;
799 
800  //The hash table is used for multicast address filtering
801  hashTable[0] = 0;
802  hashTable[1] = 0;
803 
804  //The MAC address filter contains the list of MAC addresses to accept
805  //when receiving an Ethernet frame
806  for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
807  {
808  //Point to the current entry
809  entry = &interface->macAddrFilter[i];
810 
811  //Valid entry?
812  if(entry->refCount > 0)
813  {
814  //Multicast address?
815  if(macIsMulticastAddr(&entry->addr))
816  {
817  //Compute CRC over the current MAC address
818  crc = stm32f7xxEthCalcCrc(&entry->addr, sizeof(MacAddr));
819 
820  //The upper 6 bits in the CRC register are used to index the
821  //contents of the hash table
822  k = (crc >> 26) & 0x3F;
823 
824  //Update hash table contents
825  hashTable[k / 32] |= (1 << (k % 32));
826  }
827  else
828  {
829  //Up to 3 additional MAC addresses can be specified
830  if(j < 3)
831  {
832  //Save the unicast address
833  unicastMacAddr[j++] = entry->addr;
834  }
835  }
836  }
837  }
838 
839  //Configure the first unicast address filter
840  if(j >= 1)
841  {
842  //When the AE bit is set, the entry is used for perfect filtering
843  ETH->MACA1LR = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
844  ETH->MACA1HR = unicastMacAddr[0].w[2] | ETH_MACA1HR_AE;
845  }
846  else
847  {
848  //When the AE bit is cleared, the entry is ignored
849  ETH->MACA1LR = 0;
850  ETH->MACA1HR = 0;
851  }
852 
853  //Configure the second unicast address filter
854  if(j >= 2)
855  {
856  //When the AE bit is set, the entry is used for perfect filtering
857  ETH->MACA2LR = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
858  ETH->MACA2HR = unicastMacAddr[1].w[2] | ETH_MACA2HR_AE;
859  }
860  else
861  {
862  //When the AE bit is cleared, the entry is ignored
863  ETH->MACA2LR = 0;
864  ETH->MACA2HR = 0;
865  }
866 
867  //Configure the third unicast address filter
868  if(j >= 3)
869  {
870  //When the AE bit is set, the entry is used for perfect filtering
871  ETH->MACA3LR = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
872  ETH->MACA3HR = unicastMacAddr[2].w[2] | ETH_MACA3HR_AE;
873  }
874  else
875  {
876  //When the AE bit is cleared, the entry is ignored
877  ETH->MACA3LR = 0;
878  ETH->MACA3HR = 0;
879  }
880 
881  //Configure the multicast address filter
882  ETH->MACHTLR = hashTable[0];
883  ETH->MACHTHR = hashTable[1];
884 
885  //Debug message
886  TRACE_DEBUG(" MACHTLR = %08" PRIX32 "\r\n", ETH->MACHTLR);
887  TRACE_DEBUG(" MACHTHR = %08" PRIX32 "\r\n", ETH->MACHTHR);
888 
889  //Successful processing
890  return NO_ERROR;
891 }
892 
893 
894 /**
895  * @brief Adjust MAC configuration parameters for proper operation
896  * @param[in] interface Underlying network interface
897  * @return Error code
898  **/
899 
901 {
902  uint32_t config;
903 
904  //Read current MAC configuration
905  config = ETH->MACCR;
906 
907  //10BASE-T or 100BASE-TX operation mode?
908  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
909  config |= ETH_MACCR_FES;
910  else
911  config &= ~ETH_MACCR_FES;
912 
913  //Half-duplex or full-duplex mode?
914  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
915  config |= ETH_MACCR_DM;
916  else
917  config &= ~ETH_MACCR_DM;
918 
919  //Update MAC configuration register
920  ETH->MACCR = config;
921 
922  //Successful processing
923  return NO_ERROR;
924 }
925 
926 
927 /**
928  * @brief Write PHY register
929  * @param[in] opcode Access type (2 bits)
930  * @param[in] phyAddr PHY address (5 bits)
931  * @param[in] regAddr Register address (5 bits)
932  * @param[in] data Register value
933  **/
934 
935 void stm32f7xxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
936  uint8_t regAddr, uint16_t data)
937 {
938 #if defined(STM32F7XX_ETH_MDC_PIN) && defined(STM32F7XX_ETH_MDIO_PIN)
939  //Synchronization pattern
941  //Start of frame
943  //Set up a write operation
945  //Write PHY address
946  stm32f7xxEthWriteSmi(phyAddr, 5);
947  //Write register address
949  //Turnaround
951  //Write register value
953  //Release MDIO
955 #else
956  //Valid opcode?
957  if(opcode == SMI_OPCODE_WRITE)
958  {
959  uint32_t temp;
960 
961  //Take care not to alter MDC clock configuration
962  temp = ETH->MACMIIAR & ETH_MACMIIAR_CR;
963  //Set up a write operation
964  temp |= ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
965  //PHY address
966  temp |= (phyAddr << 11) & ETH_MACMIIAR_PA;
967  //Register address
968  temp |= (regAddr << 6) & ETH_MACMIIAR_MR;
969 
970  //Data to be written in the PHY register
971  ETH->MACMIIDR = data & ETH_MACMIIDR_MD;
972 
973  //Start a write operation
974  ETH->MACMIIAR = temp;
975  //Wait for the write to complete
976  while(ETH->MACMIIAR & ETH_MACMIIAR_MB)
977  {
978  }
979  }
980  else
981  {
982  //The MAC peripheral only supports standard Clause 22 opcodes
983  }
984 #endif
985 }
986 
987 
988 /**
989  * @brief Read PHY register
990  * @param[in] opcode Access type (2 bits)
991  * @param[in] phyAddr PHY address (5 bits)
992  * @param[in] regAddr Register address (5 bits)
993  * @return Register value
994  **/
995 
996 uint16_t stm32f7xxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
997  uint8_t regAddr)
998 {
999  uint16_t data;
1000 
1001 #if defined(STM32F7XX_ETH_MDC_PIN) && defined(STM32F7XX_ETH_MDIO_PIN)
1002  //Synchronization pattern
1004  //Start of frame
1006  //Set up a read operation
1008  //Write PHY address
1009  stm32f7xxEthWriteSmi(phyAddr, 5);
1010  //Write register address
1012  //Turnaround to avoid contention
1014  //Read register value
1015  data = stm32f7xxEthReadSmi(16);
1016  //Force the PHY to release the MDIO pin
1018 #else
1019  //Valid opcode?
1020  if(opcode == SMI_OPCODE_READ)
1021  {
1022  uint32_t temp;
1023 
1024  //Take care not to alter MDC clock configuration
1025  temp = ETH->MACMIIAR & ETH_MACMIIAR_CR;
1026  //Set up a read operation
1027  temp |= ETH_MACMIIAR_MB;
1028  //PHY address
1029  temp |= (phyAddr << 11) & ETH_MACMIIAR_PA;
1030  //Register address
1031  temp |= (regAddr << 6) & ETH_MACMIIAR_MR;
1032 
1033  //Start a read operation
1034  ETH->MACMIIAR = temp;
1035  //Wait for the read to complete
1036  while(ETH->MACMIIAR & ETH_MACMIIAR_MB)
1037  {
1038  }
1039 
1040  //Get register value
1041  data = ETH->MACMIIDR & ETH_MACMIIDR_MD;
1042  }
1043  else
1044  {
1045  //The MAC peripheral only supports standard Clause 22 opcodes
1046  data = 0;
1047  }
1048 #endif
1049 
1050  //Return the value of the PHY register
1051  return data;
1052 }
1053 
1054 
1055 /**
1056  * @brief SMI write operation
1057  * @param[in] data Raw data to be written
1058  * @param[in] length Number of bits to be written
1059  **/
1060 
1062 {
1063 #if defined(STM32F7XX_ETH_MDC_PIN) && defined(STM32F7XX_ETH_MDIO_PIN)
1064  GPIO_InitTypeDef GPIO_InitStructure;
1065 
1066  //Skip the most significant bits since they are meaningless
1067  data <<= 32 - length;
1068 
1069  //Configure MDIO as an output
1070  GPIO_InitStructure.Pin = STM32F7XX_ETH_MDIO_PIN;
1071  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
1072  GPIO_InitStructure.Pull = GPIO_NOPULL;
1073  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
1074  HAL_GPIO_Init(STM32F7XX_ETH_MDIO_GPIO, &GPIO_InitStructure);
1075 
1076  //Write the specified number of bits
1077  while(length--)
1078  {
1079  //Write MDIO
1080  if(data & 0x80000000)
1081  {
1082  HAL_GPIO_WritePin(STM32F7XX_ETH_MDIO_GPIO,
1083  STM32F7XX_ETH_MDIO_PIN, GPIO_PIN_SET);
1084  }
1085  else
1086  {
1087  HAL_GPIO_WritePin(STM32F7XX_ETH_MDIO_GPIO,
1088  STM32F7XX_ETH_MDIO_PIN, GPIO_PIN_RESET);
1089  }
1090 
1091  //Delay
1092  usleep(1);
1093 
1094  //Assert MDC
1095  HAL_GPIO_WritePin(STM32F7XX_ETH_MDC_GPIO,
1096  STM32F7XX_ETH_MDC_PIN, GPIO_PIN_SET);
1097 
1098  //Delay
1099  usleep(1);
1100 
1101  //Deassert MDC
1102  HAL_GPIO_WritePin(STM32F7XX_ETH_MDC_GPIO,
1103  STM32F7XX_ETH_MDC_PIN, GPIO_PIN_RESET);
1104 
1105  //Rotate data
1106  data <<= 1;
1107  }
1108 #endif
1109 }
1110 
1111 
1112 /**
1113  * @brief SMI read operation
1114  * @param[in] length Number of bits to be read
1115  * @return Data resulting from the MDIO read operation
1116  **/
1117 
1119 {
1120  uint32_t data = 0;
1121 
1122 #if defined(STM32F7XX_ETH_MDC_PIN) && defined(STM32F7XX_ETH_MDIO_PIN)
1123  GPIO_InitTypeDef GPIO_InitStructure;
1124 
1125  //Configure MDIO as an input
1126  GPIO_InitStructure.Pin = STM32F7XX_ETH_MDIO_PIN;
1127  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
1128  GPIO_InitStructure.Pull = GPIO_PULLUP;
1129  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
1130  HAL_GPIO_Init(STM32F7XX_ETH_MDIO_GPIO, &GPIO_InitStructure);
1131 
1132  //Read the specified number of bits
1133  while(length--)
1134  {
1135  //Rotate data
1136  data <<= 1;
1137 
1138  //Assert MDC
1139  HAL_GPIO_WritePin(STM32F7XX_ETH_MDC_GPIO,
1140  STM32F7XX_ETH_MDC_PIN, GPIO_PIN_SET);
1141 
1142  //Delay
1143  usleep(1);
1144 
1145  //Deassert MDC
1146  HAL_GPIO_WritePin(STM32F7XX_ETH_MDC_GPIO,
1147  STM32F7XX_ETH_MDC_PIN, GPIO_PIN_RESET);
1148 
1149  //Delay
1150  usleep(1);
1151 
1152  //Check MDIO state
1153  if(HAL_GPIO_ReadPin(STM32F7XX_ETH_MDIO_GPIO, STM32F7XX_ETH_MDIO_PIN))
1154  data |= 0x00000001;
1155  }
1156 #endif
1157 
1158  //Return the received data
1159  return data;
1160 }
1161 
1162 
1163 /**
1164  * @brief CRC calculation
1165  * @param[in] data Pointer to the data over which to calculate the CRC
1166  * @param[in] length Number of bytes to process
1167  * @return Resulting CRC value
1168  **/
1169 
1170 uint32_t stm32f7xxEthCalcCrc(const void *data, size_t length)
1171 {
1172  uint_t i;
1173  uint_t j;
1174 
1175  //Point to the data over which to calculate the CRC
1176  const uint8_t *p = (uint8_t *) data;
1177  //CRC preset value
1178  uint32_t crc = 0xFFFFFFFF;
1179 
1180  //Loop through data
1181  for(i = 0; i < length; i++)
1182  {
1183  //The message is processed bit by bit
1184  for(j = 0; j < 8; j++)
1185  {
1186  //Update CRC value
1187  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
1188  crc = (crc << 1) ^ 0x04C11DB7;
1189  else
1190  crc = crc << 1;
1191  }
1192  }
1193 
1194  //Return CRC value
1195  return ~crc;
1196 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define usleep(delay)
Definition: os_port.h:127
uint8_t length
Definition: dtls_misc.h:149
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
#define STM32F7XX_ETH_IRQ_SUB_PRIORITY
#define ETH_TDES0_IC
uint16_t stm32f7xxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void stm32f7xxEthDisableIrq(NetInterface *interface)
Disable interrupts.
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:119
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:672
#define ETH_TDES0_TCH
void stm32f7xxEthWriteSmi(uint32_t data, uint_t length)
SMI write operation.
#define STM32F7XX_ETH_TX_BUFFER_SIZE
void stm32f7xxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
uint8_t p
Definition: ndp.h:298
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
uint32_t stm32f7xxEthCalcCrc(const void *data, size_t length)
CRC calculation.
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
#define SMI_TA
Definition: nic.h:64
error_t stm32f7xxEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define SMI_START
Definition: nic.h:60
#define ETH_RDES0_OWN
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:110
error_t stm32f7xxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:62
#define STM32F7XX_ETH_RX_BUFFER_SIZE
#define FALSE
Definition: os_port.h:46
#define ETH_RDES1_RBS1
error_t
Error codes.
Definition: error.h:42
#define STM32F7XX_ETH_TX_BUFFER_COUNT
#define ETH_RDES0_FL
uint32_t stm32f7xxEthReadSmi(uint_t length)
SMI read operation.
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
void stm32f7xxEthEnableIrq(NetInterface *interface)
Enable interrupts.
const NicDriver stm32f7xxEthDriver
STM32F7 Ethernet MAC driver.
#define txBuffer
@ ERROR_INVALID_PACKET
Definition: error.h:138
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
@ ERROR_INVALID_LENGTH
Definition: error.h:109
@ ERROR_BUFFER_EMPTY
Definition: error.h:139
#define ETH_RDES0_LS
void stm32f7xxEthTick(NetInterface *interface)
STM32F7 Ethernet MAC timer handler.
void ETH_IRQHandler(void)
STM32F7 Ethernet MAC interrupt service routine.
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
#define TRACE_INFO(...)
Definition: debug.h:94
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:62
#define rxBuffer
#define ETH_RDES1_RCH
#define STM32F7XX_ETH_IRQ_PRIORITY_GROUPING
error_t stm32f7xxEthInit(NetInterface *interface)
STM32F7 Ethernet MAC initialization.
error_t stm32f7xxEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define TRACE_DEBUG(...)
Definition: debug.h:106
#define STM32F7XX_ETH_IRQ_GROUP_PRIORITY
STM32F7 Ethernet MAC controller.
Enhanced TX DMA descriptor.
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
void stm32f7xxEthEventHandler(NetInterface *interface)
STM32F7 Ethernet MAC event handler.
#define STM32F7XX_ETH_RX_BUFFER_COUNT
#define ETH_TDES0_LS
#define osEnterIsr()
error_t stm32f7xxEthReceivePacket(NetInterface *interface)
Receive a packet.
#define rxDmaDesc
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define ETH_TDES0_FS
#define txDmaDesc
void stm32f7xxEthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
Enhanced RX DMA descriptor.
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:106
#define ETH_RDES0_ES
#define SMI_SYNC
Definition: nic.h:59
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
NIC driver.
Definition: nic.h:179
void stm32f7xxEthInitGpio(NetInterface *interface)
#define ETH_TDES0_OWN
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
__start_packed struct @108 MacAddr
MAC address.
#define ETH_TDES1_TBS1
#define ETH_RDES0_FS
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:79