xmc4800_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file xmc4800_eth_driver.c
3  * @brief Infineon XMC4800 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 "xmc4800.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 = "ETH_RAM"
48 //Receive buffer
49 #pragma data_alignment = 4
50 #pragma location = "ETH_RAM"
52 //Transmit DMA descriptors
53 #pragma data_alignment = 4
54 #pragma location = "ETH_RAM"
56 //Receive DMA descriptors
57 #pragma data_alignment = 4
58 #pragma location = "ETH_RAM"
60 
61 //Keil MDK-ARM or GCC compiler?
62 #else
63 
64 //Transmit buffer
66  __attribute__((aligned(4), __section__("ETH_RAM")));
67 //Receive buffer
69  __attribute__((aligned(4), __section__("ETH_RAM")));
70 //Transmit DMA descriptors
72  __attribute__((aligned(4), __section__("ETH_RAM")));
73 //Receive DMA descriptors
75  __attribute__((aligned(4), __section__("ETH_RAM")));
76 
77 #endif
78 
79 //Pointer to the current TX DMA descriptor
80 static Xmc4800TxDmaDesc *txCurDmaDesc;
81 //Pointer to the current RX DMA descriptor
82 static Xmc4800RxDmaDesc *rxCurDmaDesc;
83 
84 
85 /**
86  * @brief XMC4800 Ethernet MAC driver
87  **/
88 
90 {
92  ETH_MTU,
103  TRUE,
104  TRUE,
105  TRUE,
106  FALSE
107 };
108 
109 
110 /**
111  * @brief XMC4800 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 XMC4800 Ethernet MAC...\r\n");
122 
123  //Save underlying network interface
124  nicDriverInterface = interface;
125 
126  //Disable parity error trap
127  SCU_PARITY->PETE = 0;
128  //Disable unaligned access trap
129  PPB->CCR &= ~PPB_CCR_UNALIGN_TRP_Msk;
130 
131  //Enable ETH0 peripheral clock
132  SCU_CLK->CLKSET = SCU_CLK_CLKSET_ETH0CEN_Msk;
133 
134  //GPIO configuration
135  xmc4800EthInitGpio(interface);
136 
137  //Reset ETH0 peripheral
138  SCU_RESET->PRSET2 = SCU_RESET_PRSET2_ETH0RS_Msk;
139  SCU_RESET->PRCLR2 = SCU_RESET_PRCLR2_ETH0RS_Msk;
140 
141  //Reset DMA controller
142  ETH0->BUS_MODE |= ETH_BUS_MODE_SWR_Msk;
143  //Wait for the reset to complete
144  while(ETH0->BUS_MODE & ETH_BUS_MODE_SWR_Msk);
145 
146  //Adjust MDC clock range depending on ETH clock frequency
147  ETH0->GMII_ADDRESS = ETH_GMII_ADDRESS_CR_DIV62;
148 
149  //PHY transceiver initialization
150  error = interface->phyDriver->init(interface);
151  //Failed to initialize PHY transceiver?
152  if(error)
153  return error;
154 
155  //Use default MAC configuration
156  ETH0->MAC_CONFIGURATION = ETH_MAC_CONFIGURATION_RESERVED15_Msk |
157  ETH_MAC_CONFIGURATION_DO_Msk;
158 
159  //Set the MAC address
160  ETH0->MAC_ADDRESS0_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
161  ETH0->MAC_ADDRESS0_HIGH = interface->macAddr.w[2];
162 
163  //Initialize hash table
164  ETH0->HASH_TABLE_LOW = 0;
165  ETH0->HASH_TABLE_HIGH = 0;
166 
167  //Configure the receive filter
168  ETH0->MAC_FRAME_FILTER = ETH_MAC_FRAME_FILTER_HPF_Msk | ETH_MAC_FRAME_FILTER_HMC_Msk;
169  //Disable flow control
170  ETH0->FLOW_CONTROL = 0;
171  //Enable store and forward mode
172  ETH0->OPERATION_MODE = ETH_OPERATION_MODE_RSF_Msk | ETH_OPERATION_MODE_TSF_Msk;
173 
174  //Configure DMA bus mode
175  ETH0->BUS_MODE = ETH_BUS_MODE_AAL_Msk | ETH_BUS_MODE_USP_Msk |
177 
178  //Initialize DMA descriptor lists
179  xmc4800EthInitDmaDesc(interface);
180 
181  //Prevent interrupts from being generated when statistic counters reach
182  //half their maximum value
183  ETH0->MMC_TRANSMIT_INTERRUPT_MASK = 0xFFFFFFFF;
184  ETH0->MMC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
185  ETH0->MMC_IPC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF;
186 
187  //Disable MAC interrupts
188  ETH0->INTERRUPT_MASK = ETH_INTERRUPT_MASK_TSIM_Msk | ETH_INTERRUPT_MASK_PMTIM_Msk;
189 
190  //Enable the desired DMA interrupts
191  ETH0->INTERRUPT_ENABLE = ETH_INTERRUPT_ENABLE_NIE_Msk |
192  ETH_INTERRUPT_ENABLE_RIE_Msk | ETH_INTERRUPT_ENABLE_TIE_Msk;
193 
194  //Set priority grouping (6 bits for pre-emption priority, no bits for subpriority)
195  NVIC_SetPriorityGrouping(XMC4800_ETH_IRQ_PRIORITY_GROUPING);
196 
197  //Configure Ethernet interrupt priority
198  NVIC_SetPriority(ETH0_0_IRQn, NVIC_EncodePriority(XMC4800_ETH_IRQ_PRIORITY_GROUPING,
200 
201  //Enable MAC transmission and reception
202  ETH0->MAC_CONFIGURATION |= ETH_MAC_CONFIGURATION_TE_Msk | ETH_MAC_CONFIGURATION_RE_Msk;
203  //Enable DMA transmission and reception
204  ETH0->OPERATION_MODE |= ETH_OPERATION_MODE_ST_Msk | ETH_OPERATION_MODE_SR_Msk;
205 
206  //Accept any packets from the upper layer
207  osSetEvent(&interface->nicTxEvent);
208 
209  //Successful initialization
210  return NO_ERROR;
211 }
212 
213 
214 //XMC4800 Relax EtherCAT Kit?
215 #if defined(USE_XMC4800_RELAX_ECAT_KIT)
216 
217 /**
218  * @brief GPIO configuration
219  * @param[in] interface Underlying network interface
220  **/
221 
222 void xmc4800EthInitGpio(NetInterface *interface)
223 {
224  uint32_t temp;
225 
226  //Configure ETH0.MDIO (P2.0), ETH0.RXD0A (P2.2) and ETH0.RXD1A (P2.3)
227  temp = PORT2->IOCR0;
228  temp &= ~(PORT2_IOCR0_PC0_Msk | PORT2_IOCR0_PC2_Msk | PORT2_IOCR0_PC3_Msk);
229  temp |= (0UL << PORT2_IOCR0_PC0_Pos) | (0UL << PORT2_IOCR0_PC2_Pos) | (0UL << PORT2_IOCR0_PC3_Pos);
230  PORT2->IOCR0 = temp;
231 
232  //Configure ETH0.RXERA (P2.4), ETH0.TX_EN (P2.5) and ETH0.MDC (P2.7)
233  temp = PORT2->IOCR4;
234  temp &= ~(PORT2_IOCR4_PC4_Msk | PORT2_IOCR4_PC5_Msk | PORT2_IOCR4_PC7_Msk);
235  temp |= (0UL << PORT2_IOCR4_PC4_Pos) | (17UL << PORT2_IOCR4_PC5_Pos) | (17UL << PORT2_IOCR4_PC7_Pos);
236  PORT2->IOCR4 = temp;
237 
238  //Configure ETH0.TXD0 (P2.8) and ETH0.TXD1 (P2.9)
239  temp = PORT2->IOCR8;
240  temp &= ~(PORT2_IOCR8_PC8_Msk | PORT2_IOCR8_PC9_Msk);
241  temp |= (17UL << PORT2_IOCR8_PC8_Pos) | (17UL << PORT2_IOCR8_PC9_Pos);
242  PORT2->IOCR8 = temp;
243 
244  //Configure ETH0.CLK_RMIIC (P15.8) and ETH0.CRS_DVC (P15.9)
245  temp = PORT15->IOCR8;
246  temp &= ~(PORT15_IOCR8_PC8_Msk | PORT15_IOCR8_PC9_Msk);
247  temp |= (0UL << PORT15_IOCR8_PC8_Pos) | (0UL << PORT15_IOCR8_PC9_Pos);
248  PORT15->IOCR8 = temp;
249 
250  //Assign ETH_MDIO (P2.0) to HW0
251  temp = PORT2->HWSEL & ~PORT2_HWSEL_HW0_Msk;
252  PORT2->HWSEL = temp | (1UL << PORT2_HWSEL_HW0_Pos);
253 
254  //Select output driver strength for ETH0.TX_EN (P2.5)
255  temp = PORT2->PDR0;
256  temp &= ~PORT2_PDR0_PD5_Msk;
257  temp |= (0UL << PORT2_PDR0_PD5_Pos);
258  PORT2->PDR0 = temp;
259 
260  //Select output driver strength for ETH0.TXD0 (P2.8) and ETH0.TXD1 (P2.9)
261  temp = PORT2->PDR1;
262  temp &= ~(PORT2_PDR1_PD8_Msk | PORT2_PDR1_PD9_Msk);
263  temp |= (0UL << PORT2_PDR1_PD8_Pos) | (0UL << PORT2_PDR1_PD9_Pos);
264  PORT2->PDR1 = temp;
265 
266  //Use ETH0.CLK_RMIIC (P15.8) and ETH0.CRS_DVC (P15.9) as digital inputs
267  PORT15->PDISC &= ~(PORT15_PDISC_PDIS8_Msk | PORT15_PDISC_PDIS9_Msk);
268 
269  //Select RMII operation mode
270  ETH0_CON->CON = ETH_CON_INFSEL_Msk | ETH_CON_MDIO_B | ETH_CON_RXER_A |
272 }
273 
274 #endif
275 
276 
277 /**
278  * @brief Initialize DMA descriptor lists
279  * @param[in] interface Underlying network interface
280  **/
281 
283 {
284  uint_t i;
285 
286  //Initialize TX DMA descriptor list
287  for(i = 0; i < XMC4800_ETH_TX_BUFFER_COUNT; i++)
288  {
289  //Use chain structure rather than ring structure
290  txDmaDesc[i].tdes0 = ETH_TDES0_IC | ETH_TDES0_TCH;
291  //Initialize transmit buffer size
292  txDmaDesc[i].tdes1 = 0;
293  //Transmit buffer address
294  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
295  //Next descriptor address
296  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
297  }
298 
299  //The last descriptor is chained to the first entry
300  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
301  //Point to the very first descriptor
302  txCurDmaDesc = &txDmaDesc[0];
303 
304  //Initialize RX DMA descriptor list
305  for(i = 0; i < XMC4800_ETH_RX_BUFFER_COUNT; i++)
306  {
307  //The descriptor is initially owned by the DMA
308  rxDmaDesc[i].rdes0 = ETH_RDES0_OWN;
309  //Use chain structure rather than ring structure
311  //Receive buffer address
312  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
313  //Next descriptor address
314  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
315  }
316 
317  //The last descriptor is chained to the first entry
318  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
319  //Point to the very first descriptor
320  rxCurDmaDesc = &rxDmaDesc[0];
321 
322  //Start location of the TX descriptor list
323  ETH0->TRANSMIT_DESCRIPTOR_LIST_ADDRESS = (uint32_t) txDmaDesc;
324  //Start location of the RX descriptor list
325  ETH0->RECEIVE_DESCRIPTOR_LIST_ADDRESS = (uint32_t) rxDmaDesc;
326 }
327 
328 
329 /**
330  * @brief XMC4800 Ethernet MAC timer handler
331  *
332  * This routine is periodically called by the TCP/IP stack to
333  * handle periodic operations such as polling the link state
334  *
335  * @param[in] interface Underlying network interface
336  **/
337 
338 void xmc4800EthTick(NetInterface *interface)
339 {
340  //Handle periodic operations
341  interface->phyDriver->tick(interface);
342 }
343 
344 
345 /**
346  * @brief Enable interrupts
347  * @param[in] interface Underlying network interface
348  **/
349 
351 {
352  //Enable Ethernet MAC interrupts
353  NVIC_EnableIRQ(ETH0_0_IRQn);
354  //Enable Ethernet PHY interrupts
355  interface->phyDriver->enableIrq(interface);
356 }
357 
358 
359 /**
360  * @brief Disable interrupts
361  * @param[in] interface Underlying network interface
362  **/
363 
365 {
366  //Disable Ethernet MAC interrupts
367  NVIC_DisableIRQ(ETH0_0_IRQn);
368  //Disable Ethernet PHY interrupts
369  interface->phyDriver->disableIrq(interface);
370 }
371 
372 
373 /**
374  * @brief XMC4800 Ethernet MAC interrupt service routine
375  **/
376 
378 {
379  bool_t flag;
380  uint32_t status;
381 
382  //Enter interrupt service routine
383  osEnterIsr();
384 
385  //This flag will be set if a higher priority task must be woken
386  flag = FALSE;
387 
388  //Read DMA status register
389  status = ETH0->STATUS;
390 
391  //A packet has been transmitted?
392  if(status & ETH_STATUS_TI_Msk)
393  {
394  //Clear TI interrupt flag
395  ETH0->STATUS = ETH_STATUS_TI_Msk;
396 
397  //Check whether the TX buffer is available for writing
398  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
399  {
400  //Notify the TCP/IP stack that the transmitter is ready to send
401  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
402  }
403  }
404 
405  //A packet has been received?
406  if(status & ETH_STATUS_RI_Msk)
407  {
408  //Disable RIE interrupt
409  ETH0->INTERRUPT_ENABLE &= ~ETH_INTERRUPT_ENABLE_RIE_Msk;
410 
411  //Set event flag
412  nicDriverInterface->nicEvent = TRUE;
413  //Notify the TCP/IP stack of the event
414  flag |= osSetEventFromIsr(&netEvent);
415  }
416 
417  //Clear NIS interrupt flag
418  ETH0->STATUS = ETH_STATUS_NIS_Msk;
419 
420  //Leave interrupt service routine
421  osExitIsr(flag);
422 }
423 
424 
425 /**
426  * @brief XMC4800 Ethernet MAC event handler
427  * @param[in] interface Underlying network interface
428  **/
429 
431 {
432  error_t error;
433 
434  //Packet received?
435  if(ETH0->STATUS & ETH_STATUS_RI_Msk)
436  {
437  //Clear interrupt flag
438  ETH0->STATUS = ETH_STATUS_RI_Msk;
439 
440  //Process all pending packets
441  do
442  {
443  //Read incoming packet
444  error = xmc4800EthReceivePacket(interface);
445 
446  //No more data in the receive buffer?
447  } while(error != ERROR_BUFFER_EMPTY);
448  }
449 
450  //Re-enable DMA interrupts
451  ETH0->INTERRUPT_ENABLE |= ETH_INTERRUPT_ENABLE_NIE_Msk |
452  ETH_INTERRUPT_ENABLE_RIE_Msk | ETH_INTERRUPT_ENABLE_TIE_Msk;
453 }
454 
455 
456 /**
457  * @brief Send a packet
458  * @param[in] interface Underlying network interface
459  * @param[in] buffer Multi-part buffer containing the data to send
460  * @param[in] offset Offset to the first data byte
461  * @return Error code
462  **/
463 
465  const NetBuffer *buffer, size_t offset)
466 {
467  size_t length;
468 
469  //Retrieve the length of the packet
470  length = netBufferGetLength(buffer) - offset;
471 
472  //Check the frame length
474  {
475  //The transmitter can accept another packet
476  osSetEvent(&interface->nicTxEvent);
477  //Report an error
478  return ERROR_INVALID_LENGTH;
479  }
480 
481  //Make sure the current buffer is available for writing
482  if(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)
483  return ERROR_FAILURE;
484 
485  //Copy user data to the transmit buffer
486  netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length);
487 
488  //Write the number of bytes to send
489  txCurDmaDesc->tdes1 = length & ETH_TDES1_TBS1;
490  //Set LS and FS flags as the data fits in a single buffer
491  txCurDmaDesc->tdes0 |= ETH_TDES0_LS | ETH_TDES0_FS;
492  //Give the ownership of the descriptor to the DMA
493  txCurDmaDesc->tdes0 |= ETH_TDES0_OWN;
494 
495  //Clear TU flag to resume processing
496  ETH0->STATUS = ETH_STATUS_TU_Msk;
497  //Instruct the DMA to poll the transmit descriptor list
498  ETH0->TRANSMIT_POLL_DEMAND = 0;
499 
500  //Point to the next descriptor in the list
501  txCurDmaDesc = (Xmc4800TxDmaDesc *) txCurDmaDesc->tdes3;
502 
503  //Check whether the next buffer is available for writing
504  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
505  {
506  //The transmitter can accept another packet
507  osSetEvent(&interface->nicTxEvent);
508  }
509 
510  //Data successfully written
511  return NO_ERROR;
512 }
513 
514 
515 /**
516  * @brief Receive a packet
517  * @param[in] interface Underlying network interface
518  * @return Error code
519  **/
520 
522 {
523  error_t error;
524  size_t n;
525 
526  //The current buffer is available for reading?
527  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_OWN))
528  {
529  //FS and LS flags should be set
530  if((rxCurDmaDesc->rdes0 & ETH_RDES0_FS) && (rxCurDmaDesc->rdes0 & ETH_RDES0_LS))
531  {
532  //Make sure no error occurred
533  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_ES))
534  {
535  //Retrieve the length of the frame
536  n = (rxCurDmaDesc->rdes0 & ETH_RDES0_FL) >> 16;
537  //Limit the number of data to read
539 
540  //Pass the packet to the upper layer
541  nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n);
542 
543  //Valid packet received
544  error = NO_ERROR;
545  }
546  else
547  {
548  //The received packet contains an error
549  error = ERROR_INVALID_PACKET;
550  }
551  }
552  else
553  {
554  //The packet is not valid
555  error = ERROR_INVALID_PACKET;
556  }
557 
558  //Give the ownership of the descriptor back to the DMA
559  rxCurDmaDesc->rdes0 = ETH_RDES0_OWN;
560  //Point to the next descriptor in the list
561  rxCurDmaDesc = (Xmc4800RxDmaDesc *) rxCurDmaDesc->rdes3;
562  }
563  else
564  {
565  //No more data in the receive buffer
566  error = ERROR_BUFFER_EMPTY;
567  }
568 
569  //Clear RU flag to resume processing
570  ETH0->STATUS = ETH_STATUS_RU_Msk;
571  //Instruct the DMA to poll the receive descriptor list
572  ETH0->RECEIVE_POLL_DEMAND = 0;
573 
574  //Return status code
575  return error;
576 }
577 
578 
579 /**
580  * @brief Configure MAC address filtering
581  * @param[in] interface Underlying network interface
582  * @return Error code
583  **/
584 
586 {
587  uint_t i;
588  uint_t k;
589  uint32_t crc;
590  uint32_t hashTable[2];
591  MacFilterEntry *entry;
592 
593  //Debug message
594  TRACE_DEBUG("Updating XMC4800 hash table...\r\n");
595 
596  //Clear hash table
597  hashTable[0] = 0;
598  hashTable[1] = 0;
599 
600  //The MAC address filter contains the list of MAC addresses to accept
601  //when receiving an Ethernet frame
602  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
603  {
604  //Point to the current entry
605  entry = &interface->macAddrFilter[i];
606 
607  //Valid entry?
608  if(entry->refCount > 0)
609  {
610  //Compute CRC over the current MAC address
611  crc = xmc4800EthCalcCrc(&entry->addr, sizeof(MacAddr));
612 
613  //The upper 6 bits in the CRC register are used to index the
614  //contents of the hash table
615  k = (crc >> 26) & 0x3F;
616 
617  //Update hash table contents
618  hashTable[k / 32] |= (1 << (k % 32));
619  }
620  }
621 
622  //Write the hash table
623  ETH0->HASH_TABLE_LOW = hashTable[0];
624  ETH0->HASH_TABLE_HIGH = hashTable[1];
625 
626  //Debug message
627  TRACE_DEBUG(" HTL = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_LOW);
628  TRACE_DEBUG(" HTH = %08" PRIX32 "\r\n", ETH0->HASH_TABLE_HIGH);
629 
630  //Successful processing
631  return NO_ERROR;
632 }
633 
634 
635 /**
636  * @brief Adjust MAC configuration parameters for proper operation
637  * @param[in] interface Underlying network interface
638  * @return Error code
639  **/
640 
642 {
643  uint32_t config;
644 
645  //Read current MAC configuration
646  config = ETH0->MAC_CONFIGURATION;
647 
648  //10BASE-T or 100BASE-TX operation mode?
649  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
650  config |= ETH_MAC_CONFIGURATION_FES_Msk;
651  else
652  config &= ~ETH_MAC_CONFIGURATION_FES_Msk;
653 
654  //Half-duplex or full-duplex mode?
655  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
656  config |= ETH_MAC_CONFIGURATION_DM_Msk;
657  else
658  config &= ~ETH_MAC_CONFIGURATION_DM_Msk;
659 
660  //Update MAC configuration register
661  ETH0->MAC_CONFIGURATION = config;
662 
663  //Successful processing
664  return NO_ERROR;
665 }
666 
667 
668 /**
669  * @brief Write PHY register
670  * @param[in] phyAddr PHY address
671  * @param[in] regAddr Register address
672  * @param[in] data Register value
673  **/
674 
675 void xmc4800EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
676 {
677  uint32_t value;
678 
679  //Take care not to alter MDC clock configuration
680  value = ETH0->GMII_ADDRESS & ETH_GMII_ADDRESS_CR_Msk;
681  //Set up a write operation
682  value |= ETH_GMII_ADDRESS_MW_Msk | ETH_GMII_ADDRESS_MB_Msk;
683  //PHY address
684  value |= (phyAddr << ETH_GMII_ADDRESS_PA_Pos) & ETH_GMII_ADDRESS_PA_Msk;
685  //Register address
686  value |= (regAddr << ETH_GMII_ADDRESS_MR_Pos) & ETH_GMII_ADDRESS_MR_Msk;
687 
688  //Data to be written in the PHY register
689  ETH0->GMII_DATA = data & ETH_GMII_DATA_MD_Msk;
690 
691  //Start a write operation
692  ETH0->GMII_ADDRESS = value;
693  //Wait for the write to complete
694  while(ETH0->GMII_ADDRESS & ETH_GMII_ADDRESS_MB_Msk);
695 }
696 
697 
698 /**
699  * @brief Read PHY register
700  * @param[in] phyAddr PHY address
701  * @param[in] regAddr Register address
702  * @return Register value
703  **/
704 
705 uint16_t xmc4800EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
706 {
707  uint32_t value;
708 
709  //Take care not to alter MDC clock configuration
710  value = ETH0->GMII_ADDRESS & ETH_GMII_ADDRESS_CR_Msk;
711  //Set up a read operation
712  value |= ETH_GMII_ADDRESS_MB_Msk;
713  //PHY address
714  value |= (phyAddr << ETH_GMII_ADDRESS_PA_Pos) & ETH_GMII_ADDRESS_PA_Msk;
715  //Register address
716  value |= (regAddr << ETH_GMII_ADDRESS_MR_Pos) & ETH_GMII_ADDRESS_MR_Msk;
717 
718  //Start a read operation
719  ETH0->GMII_ADDRESS = value;
720  //Wait for the read to complete
721  while(ETH0->GMII_ADDRESS & ETH_GMII_ADDRESS_MB_Msk);
722 
723  //Return PHY register contents
724  return ETH0->GMII_DATA & ETH_GMII_DATA_MD_Msk;
725 }
726 
727 
728 /**
729  * @brief CRC calculation
730  * @param[in] data Pointer to the data over which to calculate the CRC
731  * @param[in] length Number of bytes to process
732  * @return Resulting CRC value
733  **/
734 
735 uint32_t xmc4800EthCalcCrc(const void *data, size_t length)
736 {
737  uint_t i;
738  uint_t j;
739 
740  //Point to the data over which to calculate the CRC
741  const uint8_t *p = (uint8_t *) data;
742  //CRC preset value
743  uint32_t crc = 0xFFFFFFFF;
744 
745  //Loop through data
746  for(i = 0; i < length; i++)
747  {
748  //The message is processed bit by bit
749  for(j = 0; j < 8; j++)
750  {
751  //Update CRC value
752  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
753  crc = (crc << 1) ^ 0x04C11DB7;
754  else
755  crc = crc << 1;
756  }
757  }
758 
759  //Return CRC value
760  return ~crc;
761 }
#define XMC4800_ETH_RX_BUFFER_COUNT
#define txDmaDesc
MacAddr addr
MAC address.
Definition: ethernet.h:210
Infineon XMC4800 Ethernet MAC controller.
#define ETH_CON_RXD1_A
TCP/IP stack core.
Debugging facilities.
#define XMC4800_ETH_IRQ_SUB_PRIORITY
uint8_t p
Definition: ndp.h:295
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
#define XMC4800_ETH_IRQ_PRIORITY_GROUPING
#define XMC4800_ETH_RX_BUFFER_SIZE
#define rxDmaDesc
#define txBuffer
#define XMC4800_ETH_TX_BUFFER_COUNT
#define ETH_BUS_MODE_RPBL_1
error_t xmc4800EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define ETH_RDES0_OWN
#define ETH_CON_CLK_RMII_C
error_t xmc4800EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
error_t xmc4800EthInit(NetInterface *interface)
XMC4800 Ethernet MAC initialization.
void xmc4800EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define ETH_RDES0_FL
#define ETH_BUS_MODE_PBL_1
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
error_t xmc4800EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void xmc4800EthInitGpio(NetInterface *interface)
void xmc4800EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define ETH_TDES0_IC
Receive DMA descriptor.
#define ETH_TDES0_OWN
#define ETH_CON_CRS_DV_C
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
#define ETH_BUS_MODE_PR_1_1
NIC driver.
Definition: nic.h:161
#define ETH_CON_MDIO_B
#define ETH_TDES0_FS
void xmc4800EthDisableIrq(NetInterface *interface)
Disable interrupts.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define ETH_CON_RXER_A
error_t xmc4800EthReceivePacket(NetInterface *interface)
Receive a packet.
#define ETH_TDES0_LS
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_CON_RXD0_A
#define ETH_GMII_ADDRESS_CR_DIV62
#define XMC4800_ETH_IRQ_GROUP_PRIORITY
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
void xmc4800EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define rxBuffer
void ETH0_0_IRQHandler(void)
XMC4800 Ethernet MAC interrupt service routine.
#define ETH_RDES0_LS
Transmit DMA descriptor.
#define XMC4800_ETH_TX_BUFFER_SIZE
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
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
uint32_t xmc4800EthCalcCrc(const void *data, size_t length)
CRC calculation.
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
#define ETH_RDES1_RCH
uint8_t value[]
Definition: dtls_misc.h:141
const NicDriver xmc4800EthDriver
XMC4800 Ethernet MAC driver.
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
#define ETH_MAC_CONFIGURATION_RESERVED15_Msk
#define osExitIsr(flag)
#define ETH_TDES0_TCH
uint16_t xmc4800EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define ETH_TDES1_TBS1
#define osEnterIsr()
#define ETH_RDES1_RBS1
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
void xmc4800EthEventHandler(NetInterface *interface)
XMC4800 Ethernet MAC event handler.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
#define ETH_RDES0_FS
MAC filter table entry.
Definition: ethernet.h:208
#define ETH_RDES0_ES
#define TRACE_DEBUG(...)
Definition: debug.h:98
void xmc4800EthTick(NetInterface *interface)
XMC4800 Ethernet MAC timer handler.