stm32h7xx_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file stm32h7xx_eth_driver.c
3  * @brief STM32H743/753 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "stm32h7xx.h"
34 #include "core/net.h"
36 #include "debug.h"
37 
38 //Underlying network interface
39 static NetInterface *nicDriverInterface;
40 
41 //IAR EWARM compiler?
42 #if defined(__ICCARM__)
43 
44 //Transmit buffer
45 #pragma data_alignment = 4
46 #pragma location = ".ram_no_cache"
48 //Receive buffer
49 #pragma data_alignment = 4
50 #pragma location = ".ram_no_cache"
52 //Transmit DMA descriptors
53 #pragma data_alignment = 4
54 #pragma location = ".ram_no_cache"
56 //Receive DMA descriptors
57 #pragma data_alignment = 4
58 #pragma location = ".ram_no_cache"
60 
61 //Keil MDK-ARM or GCC compiler?
62 #else
63 
64 //Transmit buffer
66  __attribute__((aligned(4), __section__(".ram_no_cache")));
67 //Receive buffer
69  __attribute__((aligned(4), __section__(".ram_no_cache")));
70 //Transmit DMA descriptors
72  __attribute__((aligned(4), __section__(".ram_no_cache")));
73 //Receive DMA descriptors
75  __attribute__((aligned(4), __section__(".ram_no_cache")));
76 
77 #endif
78 
79 //Current transmit descriptor
80 static uint_t txIndex;
81 //Current receive descriptor
82 static uint_t rxIndex;
83 
84 
85 /**
86  * @brief STM32H743/753 Ethernet MAC driver
87  **/
88 
90 {
92  ETH_MTU,
103  TRUE,
104  TRUE,
105  TRUE,
106  FALSE
107 };
108 
109 
110 /**
111  * @brief STM32H743/753 Ethernet MAC initialization
112  * @param[in] interface Underlying network interface
113  * @return Error code
114  **/
115 
117 {
118  error_t error;
119 
120  //Debug message
121  TRACE_INFO("Initializing STM32H7xx Ethernet MAC...\r\n");
122 
123  //Save underlying network interface
124  nicDriverInterface = interface;
125 
126  //GPIO configuration
127  stm32h7xxEthInitGpio(interface);
128 
129  //Enable Ethernet MAC clock
130  __HAL_RCC_ETH1MAC_CLK_ENABLE();
131  __HAL_RCC_ETH1TX_CLK_ENABLE();
132  __HAL_RCC_ETH1RX_CLK_ENABLE();
133 
134  //Reset Ethernet MAC peripheral
135  __HAL_RCC_ETH1MAC_FORCE_RESET();
136  __HAL_RCC_ETH1MAC_RELEASE_RESET();
137 
138  //Perform a software reset
139  ETH->DMAMR |= ETH_DMAMR_SWR;
140  //Wait for the reset to complete
141  while(ETH->DMAMR & ETH_DMAMR_SWR);
142 
143  //Adjust MDC clock range depending on HCLK frequency
144  ETH->MACMDIOAR = ETH_MACMDIOAR_CR_DIV124;
145 
146  //PHY transceiver initialization
147  error = interface->phyDriver->init(interface);
148  //Failed to initialize PHY transceiver?
149  if(error)
150  return error;
151 
152  //Use default MAC configuration
153  ETH->MACCR = ETH_MACCR_DO;
154 
155  //Set the MAC address
156  ETH->MACA0LR = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
157  ETH->MACA0HR = interface->macAddr.w[2];
158 
159  //Initialize hash table
160  ETH->MACHT0R = 0;
161  ETH->MACHT1R = 0;
162 
163  //Configure the receive filter
164  ETH->MACPFR = ETH_MACPFR_HPF | ETH_MACPFR_HMC;
165 
166  //Disable flow control
167  ETH->MACTFCR = 0;
168  ETH->MACRFCR = 0;
169 
170  //Configure DMA operating mode
171  ETH->DMAMR = ETH_DMAMR_INTM_0 | ETH_DMAMR_PR_1_1;
172  //Configure system bus mode
173  ETH->DMASBMR |= ETH_DMASBMR_AAL;
174  //The DMA takes the descriptor table as contiguous
175  ETH->DMACCR = ETH_DMACCR_DSL_0BIT;
176 
177  //Configure TX features
178  ETH->DMACTCR = ETH_DMACTCR_TPBL_1PBL;
179 
180  //Configure RX features
181  ETH->DMACRCR = ETH_DMACRCR_RPBL_1PBL;
182  ETH->DMACRCR |= (STM32H7XX_ETH_RX_BUFFER_SIZE << 1) & ETH_DMACRCR_RBSZ;
183 
184  //Enable store and forward mode
185  ETH->MTLTQOMR |= ETH_MTLTQOMR_TSF;
186  ETH->MTLRQOMR |= ETH_MTLRQOMR_RSF;
187 
188  //Initialize DMA descriptor lists
189  stm32h7xxEthInitDmaDesc(interface);
190 
191  //Prevent interrupts from being generated when the transmit statistic
192  //counters reach half their maximum value
195 
196  //Prevent interrupts from being generated when the receive statistic
197  //counters reach half their maximum value
200 
201  //Disable MAC interrupts
202  ETH->MACIER = 0;
203  //Enable the desired DMA interrupts
204  ETH->DMACIER = ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
205 
206  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
207  NVIC_SetPriorityGrouping(STM32H7XX_ETH_IRQ_PRIORITY_GROUPING);
208 
209  //Configure Ethernet interrupt priority
210  NVIC_SetPriority(ETH_IRQn, NVIC_EncodePriority(STM32H7XX_ETH_IRQ_PRIORITY_GROUPING,
212 
213  //Enable MAC transmission and reception
214  ETH->MACCR |= ETH_MACCR_TE | ETH_MACCR_RE;
215 
216  //Enable DMA transmission and reception
217  ETH->DMACTCR |= ETH_DMACTCR_ST;
218  ETH->DMACRCR |= ETH_DMACRCR_SR;
219 
220  //Accept any packets from the upper layer
221  osSetEvent(&interface->nicTxEvent);
222 
223  //Successful initialization
224  return NO_ERROR;
225 }
226 
227 
228 //STM32F743I-EVAL or Nucleo-H743I evaluation board?
229 #if defined(USE_STM32H743I_EVAL) || defined(USE_STM32H7XX_NUCLEO_144)
230 
231 /**
232  * @brief GPIO configuration
233  * @param[in] interface Underlying network interface
234  **/
235 
236 void stm32h7xxEthInitGpio(NetInterface *interface)
237 {
238  uint32_t temp;
239  GPIO_InitTypeDef GPIO_InitStructure;
240 
241 //STM32F743I-EVAL evaluation board?
242 #if defined(USE_STM32H743I_EVAL)
243  //Enable SYSCFG clock
244  __HAL_RCC_SYSCFG_CLK_ENABLE();
245 
246  //Enable GPIO clocks
247  __HAL_RCC_GPIOA_CLK_ENABLE();
248  __HAL_RCC_GPIOC_CLK_ENABLE();
249  __HAL_RCC_GPIOG_CLK_ENABLE();
250 
251  //Select RMII interface mode
252  temp = SYSCFG->PMCR & ~SYCFG_PMCR_EPIS_SEL;
253  SYSCFG->PMCR = temp | SYSCFG_PMCR_EPIS_SEL_2;
254 
255  //Configure RMII pins
256  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
257  GPIO_InitStructure.Pull = GPIO_NOPULL;
258  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
259  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
260 
261  //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7)
262  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
263  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
264 
265  //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5)
266  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
267  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
268 
269  //Configure RMII_TX_EN (PG11), ETH_RMII_TXD1 (PG12) and ETH_RMII_TXD0 (PG13)
270  GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
271  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
272 
273 //Nucleo-H743I evaluation board?
274 #elif defined(USE_STM32H7XX_NUCLEO_144)
275  //Enable SYSCFG clock
276  __HAL_RCC_SYSCFG_CLK_ENABLE();
277 
278  //Enable GPIO clocks
279  __HAL_RCC_GPIOA_CLK_ENABLE();
280  __HAL_RCC_GPIOB_CLK_ENABLE();
281  __HAL_RCC_GPIOC_CLK_ENABLE();
282  __HAL_RCC_GPIOG_CLK_ENABLE();
283 
284  //Select RMII interface mode
285  temp = SYSCFG->PMCR & ~SYCFG_PMCR_EPIS_SEL;
286  SYSCFG->PMCR = temp | SYSCFG_PMCR_EPIS_SEL_2;
287 
288  //Configure RMII pins
289  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
290  GPIO_InitStructure.Pull = GPIO_NOPULL;
291  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
292  GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
293 
294  //Configure ETH_RMII_REF_CLK (PA1), ETH_MDIO (PA2) and ETH_RMII_CRS_DV (PA7)
295  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
296  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
297 
298  //Configure ETH_RMII_TXD1 (PB13)
299  GPIO_InitStructure.Pin = GPIO_PIN_13;
300  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
301 
302  //Configure ETH_MDC (PC1), ETH_RMII_RXD0 (PC4) and ETH_RMII_RXD1 (PC5)
303  GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
304  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
305 
306  //Configure RMII_TX_EN (PG11), ETH_RMII_TXD0 (PG13)
307  GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13;
308  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
309 #endif
310 }
311 
312 #endif
313 
314 
315 /**
316  * @brief Initialize DMA descriptor lists
317  * @param[in] interface Underlying network interface
318  **/
319 
321 {
322  uint_t i;
323 
324  //Initialize TX DMA descriptor list
325  for(i = 0; i < STM32H7XX_ETH_TX_BUFFER_COUNT; i++)
326  {
327  //The descriptor is initially owned by the application
328  txDmaDesc[i].tdes0 = 0;
329  txDmaDesc[i].tdes1 = 0;
330  txDmaDesc[i].tdes2 = 0;
331  txDmaDesc[i].tdes3 = 0;
332  }
333 
334  //Initialize TX descriptor index
335  txIndex = 0;
336 
337  //Initialize RX DMA descriptor list
338  for(i = 0; i < STM32H7XX_ETH_RX_BUFFER_COUNT; i++)
339  {
340  //The descriptor is initially owned by the DMA
341  rxDmaDesc[i].rdes0 = (uint32_t) rxBuffer[i];
342  rxDmaDesc[i].rdes1 = 0;
343  rxDmaDesc[i].rdes2 = 0;
345  }
346 
347  //Initialize RX descriptor index
348  rxIndex = 0;
349 
350  //Start location of the TX descriptor list
351  ETH->DMACTDLAR = (uint32_t) &txDmaDesc[0];
352  //Length of the transmit descriptor ring
353  ETH->DMACTDRLR = STM32H7XX_ETH_TX_BUFFER_COUNT - 1;
354 
355  //Start location of the RX descriptor list
356  ETH->DMACRDLAR = (uint32_t) &rxDmaDesc[0];
357  //Length of the receive descriptor ring
358  ETH->DMACRDRLR = STM32H7XX_ETH_RX_BUFFER_COUNT - 1;
359 }
360 
361 
362 /**
363  * @brief STM32H743/753 Ethernet MAC timer handler
364  *
365  * This routine is periodically called by the TCP/IP stack to
366  * handle periodic operations such as polling the link state
367  *
368  * @param[in] interface Underlying network interface
369  **/
370 
372 {
373  //Handle periodic operations
374  interface->phyDriver->tick(interface);
375 }
376 
377 
378 /**
379  * @brief Enable interrupts
380  * @param[in] interface Underlying network interface
381  **/
382 
384 {
385  //Enable Ethernet MAC interrupts
386  NVIC_EnableIRQ(ETH_IRQn);
387  //Enable Ethernet PHY interrupts
388  interface->phyDriver->enableIrq(interface);
389 }
390 
391 
392 /**
393  * @brief Disable interrupts
394  * @param[in] interface Underlying network interface
395  **/
396 
398 {
399  //Disable Ethernet MAC interrupts
400  NVIC_DisableIRQ(ETH_IRQn);
401  //Disable Ethernet PHY interrupts
402  interface->phyDriver->disableIrq(interface);
403 }
404 
405 
406 /**
407  * @brief STM32H743/753 Ethernet MAC interrupt service routine
408  **/
409 
410 void ETH_IRQHandler(void)
411 {
412  bool_t flag;
413  uint32_t status;
414 
415  //Enter interrupt service routine
416  osEnterIsr();
417 
418  //This flag will be set if a higher priority task must be woken
419  flag = FALSE;
420 
421  //Read DMA status register
422  status = ETH->DMACSR;
423 
424  //A packet has been transmitted?
425  if(status & ETH_DMACSR_TI)
426  {
427  //Clear TI interrupt flag
428  ETH->DMACSR = ETH_DMACSR_TI;
429 
430  //Check whether the TX buffer is available for writing
431  if(!(txDmaDesc[txIndex].tdes3 & ETH_TDES3_OWN))
432  {
433  //Notify the TCP/IP stack that the transmitter is ready to send
434  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
435  }
436  }
437 
438  //A packet has been received?
439  if(status & ETH_DMACSR_RI)
440  {
441  //Disable RIE interrupt
442  ETH->DMACIER &= ~ETH_DMACIER_RIE;
443 
444  //Set event flag
445  nicDriverInterface->nicEvent = TRUE;
446  //Notify the TCP/IP stack of the event
447  flag |= osSetEventFromIsr(&netEvent);
448  }
449 
450  //Clear NIS interrupt flag
451  ETH->DMACSR = ETH_DMACSR_NIS;
452 
453  //Leave interrupt service routine
454  osExitIsr(flag);
455 }
456 
457 
458 /**
459  * @brief STM32H743/753 Ethernet MAC event handler
460  * @param[in] interface Underlying network interface
461  **/
462 
464 {
465  error_t error;
466 
467  //Packet received?
468  if(ETH->DMACSR & ETH_DMACSR_RI)
469  {
470  //Clear interrupt flag
471  ETH->DMACSR = ETH_DMACSR_RI;
472 
473  //Process all pending packets
474  do
475  {
476  //Read incoming packet
477  error = stm32h7xxEthReceivePacket(interface);
478 
479  //No more data in the receive buffer?
480  } while(error != ERROR_BUFFER_EMPTY);
481  }
482 
483  //Re-enable DMA interrupts
484  ETH->DMACIER |= ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
485 }
486 
487 
488 /**
489  * @brief Send a packet
490  * @param[in] interface Underlying network interface
491  * @param[in] buffer Multi-part buffer containing the data to send
492  * @param[in] offset Offset to the first data byte
493  * @return Error code
494  **/
495 
497  const NetBuffer *buffer, size_t offset)
498 {
499  static uint8_t temp[STM32H7XX_ETH_TX_BUFFER_SIZE];
500  size_t length;
501 
502  //Retrieve the length of the packet
503  length = netBufferGetLength(buffer) - offset;
504 
505  //Check the frame length
507  {
508  //The transmitter can accept another packet
509  osSetEvent(&interface->nicTxEvent);
510  //Report an error
511  return ERROR_INVALID_LENGTH;
512  }
513 
514  //Make sure the current buffer is available for writing
515  if(txDmaDesc[txIndex].tdes3 & ETH_TDES3_OWN)
516  return ERROR_FAILURE;
517 
518  //Copy user data to the transmit buffer
519  netBufferRead(temp, buffer, offset, length);
520  memcpy(txBuffer[txIndex], temp, (length + 3) & ~3UL);
521 
522  //Set the start address of the buffer
523  txDmaDesc[txIndex].tdes0 = (uint32_t) txBuffer[txIndex];
524  //Write the number of bytes to send
525  txDmaDesc[txIndex].tdes2 = ETH_TDES2_IOC | (length & ETH_TDES2_B1L);
526  //Give the ownership of the descriptor to the DMA
527  txDmaDesc[txIndex].tdes3 = ETH_TDES3_OWN | ETH_TDES3_FD | ETH_TDES3_LD;
528 
529  //Data synchronization barrier
530  __DSB();
531 
532  //Clear TBU flag to resume processing
533  ETH->DMACSR = ETH_DMACSR_TBU;
534  //Instruct the DMA to poll the transmit descriptor list
535  ETH->DMACTDTPR = 0;
536 
537  //Increment index and wrap around if necessary
538  if(++txIndex >= STM32H7XX_ETH_TX_BUFFER_COUNT)
539  txIndex = 0;
540 
541  //Check whether the next buffer is available for writing
542  if(!(txDmaDesc[txIndex].tdes3 & ETH_TDES3_OWN))
543  {
544  //The transmitter can accept another packet
545  osSetEvent(&interface->nicTxEvent);
546  }
547 
548  //Data successfully written
549  return NO_ERROR;
550 }
551 
552 
553 /**
554  * @brief Receive a packet
555  * @param[in] interface Underlying network interface
556  * @return Error code
557  **/
558 
560 {
561  static uint8_t temp[STM32H7XX_ETH_RX_BUFFER_SIZE];
562  error_t error;
563  size_t n;
564 
565  //The current buffer is available for reading?
566  if(!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_OWN))
567  {
568  //FD and LD flags should be set
569  if((rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_FD) &&
570  (rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_LD))
571  {
572  //Make sure no error occurred
573  if(!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_ES))
574  {
575  //Retrieve the length of the frame
576  n = rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_PL;
577  //Limit the number of data to read
579 
580  //Copy data from the receive buffer
581  memcpy(temp, (uint8_t *) rxBuffer[rxIndex], (n + 3) & ~3UL);
582 
583  //Pass the packet to the upper layer
584  nicProcessPacket(interface, temp, n);
585 
586  //Valid packet received
587  error = NO_ERROR;
588  }
589  else
590  {
591  //The received packet contains an error
592  error = ERROR_INVALID_PACKET;
593  }
594  }
595  else
596  {
597  //The packet is not valid
598  error = ERROR_INVALID_PACKET;
599  }
600 
601  //Set the start address of the buffer
602  rxDmaDesc[rxIndex].rdes0 = (uint32_t) rxBuffer[rxIndex];
603  //Give the ownership of the descriptor back to the DMA
605 
606  //Increment index and wrap around if necessary
607  if(++rxIndex >= STM32H7XX_ETH_RX_BUFFER_COUNT)
608  rxIndex = 0;
609  }
610  else
611  {
612  //No more data in the receive buffer
613  error = ERROR_BUFFER_EMPTY;
614  }
615 
616  //Clear RBU flag to resume processing
617  ETH->DMACSR = ETH_DMACSR_RBU;
618  //Instruct the DMA to poll the receive descriptor list
619  ETH->DMACRDTPR = 0;
620 
621  //Return status code
622  return error;
623 }
624 
625 
626 /**
627  * @brief Configure MAC address filtering
628  * @param[in] interface Underlying network interface
629  * @return Error code
630  **/
631 
633 {
634  uint_t i;
635  uint_t k;
636  uint32_t crc;
637  uint32_t hashTable[2];
638  MacFilterEntry *entry;
639 
640  //Debug message
641  TRACE_DEBUG("Updating STM32H7xx hash table...\r\n");
642 
643  //Clear hash table
644  hashTable[0] = 0;
645  hashTable[1] = 0;
646 
647  //The MAC address filter contains the list of MAC addresses to accept
648  //when receiving an Ethernet frame
649  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
650  {
651  //Point to the current entry
652  entry = &interface->macAddrFilter[i];
653 
654  //Valid entry?
655  if(entry->refCount > 0)
656  {
657  //Compute CRC over the current MAC address
658  crc = stm32h7xxEthCalcCrc(&entry->addr, sizeof(MacAddr));
659 
660  //The upper 6 bits in the CRC register are used to index the
661  //contents of the hash table
662  k = (crc >> 26) & 0x3F;
663 
664  //Update hash table contents
665  hashTable[k / 32] |= (1 << (k % 32));
666  }
667  }
668 
669  //Write the hash table
670  ETH->MACHT0R = hashTable[0];
671  ETH->MACHT1R = hashTable[1];
672 
673  //Debug message
674  TRACE_DEBUG(" MACHT0R = %08" PRIX32 "\r\n", ETH->MACHT0R);
675  TRACE_DEBUG(" MACHT1R = %08" PRIX32 "\r\n", ETH->MACHT1R);
676 
677  //Successful processing
678  return NO_ERROR;
679 }
680 
681 
682 /**
683  * @brief Adjust MAC configuration parameters for proper operation
684  * @param[in] interface Underlying network interface
685  * @return Error code
686  **/
687 
689 {
690  uint32_t config;
691 
692  //Read current MAC configuration
693  config = ETH->MACCR;
694 
695  //10BASE-T or 100BASE-TX operation mode?
696  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
697  config |= ETH_MACCR_FES;
698  else
699  config &= ~ETH_MACCR_FES;
700 
701  //Half-duplex or full-duplex mode?
702  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
703  config |= ETH_MACCR_DM;
704  else
705  config &= ~ETH_MACCR_DM;
706 
707  //Update MAC configuration register
708  ETH->MACCR = config;
709 
710  //Successful processing
711  return NO_ERROR;
712 }
713 
714 
715 /**
716  * @brief Write PHY register
717  * @param[in] phyAddr PHY address
718  * @param[in] regAddr Register address
719  * @param[in] data Register value
720  **/
721 
722 void stm32h7xxEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
723 {
724  uint32_t value;
725 
726  //Take care not to alter MDC clock configuration
727  value = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
728  //Set up a write operation
729  value |= ETH_MACMDIOAR_MOC_WR | ETH_MACMDIOAR_MB;
730  //PHY address
731  value |= (phyAddr << 21) & ETH_MACMDIOAR_PA;
732  //Register address
733  value |= (regAddr << 16) & ETH_MACMDIOAR_RDA;
734 
735  //Data to be written in the PHY register
736  ETH->MACMDIODR = data & ETH_MACMDIODR_MD;
737 
738  //Start a write operation
739  ETH->MACMDIOAR = value;
740  //Wait for the write to complete
741  while(ETH->MACMDIOAR & ETH_MACMDIOAR_MB);
742 }
743 
744 
745 /**
746  * @brief Read PHY register
747  * @param[in] phyAddr PHY address
748  * @param[in] regAddr Register address
749  * @return Register value
750  **/
751 
752 uint16_t stm32h7xxEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
753 {
754  uint32_t value;
755 
756  //Take care not to alter MDC clock configuration
757  value = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
758  //Set up a read operation
759  value |= ETH_MACMDIOAR_MOC_RD | ETH_MACMDIOAR_MB;
760  //PHY address
761  value |= (phyAddr << 21) & ETH_MACMDIOAR_PA;
762  //Register address
763  value |= (regAddr << 16) & ETH_MACMDIOAR_RDA;
764 
765  //Start a read operation
766  ETH->MACMDIOAR = value;
767  //Wait for the read to complete
768  while(ETH->MACMDIOAR & ETH_MACMDIOAR_MB);
769 
770  //Return PHY register contents
771  return ETH->MACMDIODR & ETH_MACMDIODR_MD;
772 }
773 
774 
775 /**
776  * @brief CRC calculation
777  * @param[in] data Pointer to the data over which to calculate the CRC
778  * @param[in] length Number of bytes to process
779  * @return Resulting CRC value
780  **/
781 
782 uint32_t stm32h7xxEthCalcCrc(const void *data, size_t length)
783 {
784  uint_t i;
785  uint_t j;
786 
787  //Point to the data over which to calculate the CRC
788  const uint8_t *p = (uint8_t *) data;
789  //CRC preset value
790  uint32_t crc = 0xFFFFFFFF;
791 
792  //Loop through data
793  for(i = 0; i < length; i++)
794  {
795  //The message is processed bit by bit
796  for(j = 0; j < 8; j++)
797  {
798  //Update CRC value
799  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
800  crc = (crc << 1) ^ 0x04C11DB7;
801  else
802  crc = crc << 1;
803  }
804  }
805 
806  //Return CRC value
807  return ~crc;
808 }
error_t stm32h7xxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define txDmaDesc
#define ETH_RDES3_LD
MacAddr addr
MAC address.
Definition: ethernet.h:210
#define ETH_MMCTIMR_TXSCOLGPIM
void stm32h7xxEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
TCP/IP stack core.
#define ETH_RDES3_ES
#define ETH_TDES2_IOC
Debugging facilities.
uint8_t p
Definition: ndp.h:295
STM32H743/753 Ethernet MAC controller.
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
#define ETH_TDES2_B1L
void stm32h7xxEthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
Generic error code.
Definition: error.h:43
#define rxDmaDesc
error_t stm32h7xxEthReceivePacket(NetInterface *interface)
Receive a packet.
#define ETH_RDES3_BUF1V
#define ETH_MMCRIMR_RXLPIUSCIM
#define txBuffer
#define ETH_TDES3_FD
#define STM32H7XX_ETH_IRQ_GROUP_PRIORITY
#define ETH_MMCRIMR_RXALGNERPIM
error_t stm32h7xxEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define ETH_RDES3_IOC
#define ETH_MMCRIMR_RXLPITRCIM
void stm32h7xxEthEnableIrq(NetInterface *interface)
Enable interrupts.
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
Transmit descriptor.
#define STM32H7XX_ETH_RX_BUFFER_COUNT
void ETH_IRQHandler(void)
STM32H743/753 Ethernet MAC interrupt service routine.
#define ETH_MMCRIMR_RXCRCERPIM
#define ETH_RDES3_PL
uint32_t stm32h7xxEthCalcCrc(const void *data, size_t length)
CRC calculation.
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:670
NIC driver.
Definition: nic.h:161
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
Receive descriptor.
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define ETH_MMCTIMR_TXMCOLGPIM
error_t stm32h7xxEthInit(NetInterface *interface)
STM32H743/753 Ethernet MAC initialization.
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
error_t stm32h7xxEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void stm32h7xxEthTick(NetInterface *interface)
STM32H743/753 Ethernet MAC timer handler.
#define rxBuffer
#define ETH_RDES3_FD
OsEvent netEvent
Definition: net.c:72
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
uint16_t stm32h7xxEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
unsigned int uint_t
Definition: compiler_port.h:43
__start_packed struct @112 MacAddr
MAC address.
#define ETH_MMCTIMR_TXLPIUSCIM
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
#define ETH_RDES3_OWN
uint8_t value[]
Definition: dtls_misc.h:141
void stm32h7xxEthEventHandler(NetInterface *interface)
STM32H743/753 Ethernet MAC event handler.
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
#define ETH_MMCTIMR_TXGPKTIM
#define ETH_MMCTIMR_TXLPITRCIM
#define STM32H7XX_ETH_IRQ_SUB_PRIORITY
#define ETH_MMCRIMR_RXUCGPIM
#define osExitIsr(flag)
#define ETH_TDES3_LD
#define ETH_TDES3_OWN
#define osEnterIsr()
const NicDriver stm32h7xxEthDriver
STM32H743/753 Ethernet MAC driver.
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define STM32H7XX_ETH_RX_BUFFER_SIZE
void stm32h7xxEthDisableIrq(NetInterface *interface)
Disable interrupts.
#define FALSE
Definition: os_port.h:44
#define STM32H7XX_ETH_TX_BUFFER_COUNT
void stm32h7xxEthInitGpio(NetInterface *interface)
int bool_t
Definition: compiler_port.h:47
#define STM32H7XX_ETH_IRQ_PRIORITY_GROUPING
#define STM32H7XX_ETH_TX_BUFFER_SIZE
MAC filter table entry.
Definition: ethernet.h:208
#define TRACE_DEBUG(...)
Definition: debug.h:98