pic32mx_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file pic32mx_eth_driver.c
3  * @brief PIC32MX Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <p32xxxx.h>
36 #include <sys/kmem.h>
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //Transmit buffer
46  __attribute__((coherent, aligned(4)));
47 //Receive buffer
49  __attribute__((coherent, aligned(4)));
50 //Transmit buffer descriptors
52  __attribute__((coherent, aligned(4)));
53 //Receive buffer descriptors
55  __attribute__((coherent, aligned(4)));
56 
57 //Pointer to the current TX buffer descriptor
58 static Pic32mxTxBufferDesc *txCurBufferDesc;
59 //Pointer to the current RX buffer descriptor
60 static Pic32mxRxBufferDesc *rxCurBufferDesc;
61 
62 
63 /**
64  * @brief PIC32MX Ethernet MAC driver
65  **/
66 
68 {
70  ETH_MTU,
81  TRUE,
82  TRUE,
83  TRUE,
84  FALSE
85 };
86 
87 
88 /**
89  * @brief PIC32MX Ethernet MAC initialization
90  * @param[in] interface Underlying network interface
91  * @return Error code
92  **/
93 
95 {
96  error_t error;
97 
98  //Debug message
99  TRACE_INFO("Initializing PIC32MX Ethernet MAC...\r\n");
100 
101  //Save underlying network interface
102  nicDriverInterface = interface;
103 
104  //GPIO configuration
105  pic32mxEthInitGpio(interface);
106 
107  //Disable Ethernet interrupts
108  IEC1CLR = _IEC1_ETHIE_MASK;
109  //Turn the Ethernet controller off
110  ETHCON1CLR = _ETHCON1_ON_MASK | _ETHCON1_TXRTS_POSITION | _ETHCON1_RXEN_MASK;
111 
112  //Wait activity abort by polling the ETHBUSY bit
113  while((ETHSTAT & _ETHSTAT_ETHBUSY_MASK) != 0)
114  {
115  }
116 
117  //Enable the Ethernet controller by setting the ON bit
118  ETHCON1SET = _ETHCON1_ON_MASK;
119 
120  //Clear Ethernet interrupt flag
121  IFS1CLR = _IFS1_ETHIF_MASK;
122  //Disable any Ethernet controller interrupt generation
123  ETHIEN = 0;
124  ETHIRQ = 0;
125  //Clear the TX and RX start addresses
126  ETHTXST = 0;
127  ETHRXST = 0;
128 
129  //Reset the MAC using SOFTRESET
130  EMAC1CFG1SET = _EMAC1CFG1_SOFTRESET_MASK;
131  EMAC1CFG1CLR = _EMAC1CFG1_SOFTRESET_MASK;
132 
133  //Reset the RMII module
134  EMAC1SUPPSET = _EMAC1SUPP_RESETRMII_MASK;
135  EMAC1SUPPCLR = _EMAC1SUPP_RESETRMII_MASK;
136 
137  //Issue an MIIM block reset by setting the RESETMGMT bit
138  EMAC1MCFGSET = _EMAC1MCFG_RESETMGMT_MASK;
139  EMAC1MCFGCLR = _EMAC1MCFG_RESETMGMT_MASK;
140 
141  //Select the proper divider for the MDC clock
142  EMAC1MCFG = _EMAC1MCFG_CLKSEL_DIV40;
143 
144  //Valid Ethernet PHY or switch driver?
145  if(interface->phyDriver != NULL)
146  {
147  //Ethernet PHY initialization
148  error = interface->phyDriver->init(interface);
149  }
150  else if(interface->switchDriver != NULL)
151  {
152  //Ethernet switch initialization
153  error = interface->switchDriver->init(interface);
154  }
155  else
156  {
157  //The interface is not properly configured
158  error = ERROR_FAILURE;
159  }
160 
161  //Any error to report?
162  if(error)
163  {
164  return error;
165  }
166 
167  //Optionally set the station MAC address
168  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
169  {
170  //Use the factory preprogrammed station address
171  interface->macAddr.w[0] = EMAC1SA2;
172  interface->macAddr.w[1] = EMAC1SA1;
173  interface->macAddr.w[2] = EMAC1SA0;
174 
175  //Generate the 64-bit interface identifier
176  macAddrToEui64(&interface->macAddr, &interface->eui64);
177  }
178  else
179  {
180  //Override the factory preprogrammed address
181  EMAC1SA0 = interface->macAddr.w[2];
182  EMAC1SA1 = interface->macAddr.w[1];
183  EMAC1SA2 = interface->macAddr.w[0];
184  }
185 
186  //Initialize hash table
187  ETHHT0 = 0;
188  ETHHT1 = 0;
189 
190  //Configure the receive filter
191  ETHRXFC = _ETHRXFC_HTEN_MASK | _ETHRXFC_CRCOKEN_MASK |
192  _ETHRXFC_RUNTEN_MASK | _ETHRXFC_UCEN_MASK | _ETHRXFC_BCEN_MASK;
193 
194  //Disable flow control
195  EMAC1CFG1 = _EMAC1CFG1_RXENABLE_MASK;
196  //Automatic padding and CRC generation
197  EMAC1CFG2 = _EMAC1CFG2_PADENABLE_MASK | _EMAC1CFG2_CRCENABLE_MASK;
198  //Set the maximum frame length
199  EMAC1MAXF = PIC32MX_ETH_RX_BUFFER_SIZE;
200 
201  //Initialize DMA descriptor lists
202  pic32mxEthInitBufferDesc(interface);
203 
204  //Enable desired interrupts
205  ETHIENSET = _ETHIEN_PKTPENDIE_MASK | _ETHIEN_TXDONEIE_MASK;
206 
207  //Set interrupt priority
208  IPC12CLR = _IPC12_ETHIP_MASK;
209  IPC12SET = (PIC32MX_ETH_IRQ_PRIORITY << _IPC12_ETHIP_POSITION);
210  //Set interrupt subpriority
211  IPC12CLR = _IPC12_ETHIS_MASK;
212  IPC12SET = (PIC32MX_ETH_IRQ_SUB_PRIORITY << _IPC12_ETHIS_POSITION);
213 
214  //Enable the reception by setting the RXEN bit
215  ETHCON1SET = _ETHCON1_RXEN_MASK;
216 
217  //Accept any packets from the upper layer
218  osSetEvent(&interface->nicTxEvent);
219 
220  //Successful initialization
221  return NO_ERROR;
222 }
223 
224 
225 /**
226  * @brief GPIO configuration
227  * @param[in] interface Underlying network interface
228  **/
229 
230 __weak_func void pic32mxEthInitGpio(NetInterface *interface)
231 {
232 }
233 
234 
235 /**
236  * @brief Initialize DMA descriptor lists
237  * @param[in] interface Underlying network interface
238  **/
239 
241 {
242  uint_t i;
243 
244  //Initialize TX descriptor list
245  for(i = 0; i < PIC32MX_ETH_TX_BUFFER_COUNT; i++)
246  {
247  //Point to the current descriptor
248  txCurBufferDesc = &txBufferDesc[i];
249 
250  //Use linked list rather than linear list
251  txCurBufferDesc->control = ETH_TX_CTRL_NPV;
252  //Transmit buffer address
253  txCurBufferDesc->address = KVA_TO_PA(txBuffer[i]);
254  //Transmit status vector
255  txCurBufferDesc->status1 = 0;
256  txCurBufferDesc->status2 = 0;
257  //Next descriptor address
258  txCurBufferDesc->next = KVA_TO_PA(&txBufferDesc[i + 1]);
259  }
260 
261  //The last descriptor is chained to the first entry
262  txCurBufferDesc->next = KVA_TO_PA(&txBufferDesc[0]);
263  //Point to the very first descriptor
264  txCurBufferDesc = &txBufferDesc[0];
265 
266  //Initialize RX descriptor list
267  for(i = 0; i < PIC32MX_ETH_RX_BUFFER_COUNT; i++)
268  {
269  //Point to the current descriptor
270  rxCurBufferDesc = &rxBufferDesc[i];
271 
272  //The descriptor is initially owned by the DMA
273  rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
274  //Receive buffer address
275  rxCurBufferDesc->address = KVA_TO_PA(rxBuffer[i]);
276  //Receive status vector
277  rxCurBufferDesc->status1 = 0;
278  rxCurBufferDesc->status2 = 0;
279  //Next descriptor address
280  rxCurBufferDesc->next = KVA_TO_PA(&rxBufferDesc[i + 1]);
281  }
282 
283  //The last descriptor is chained to the first entry
284  rxCurBufferDesc->next = KVA_TO_PA(&rxBufferDesc[0]);
285  //Point to the very first descriptor
286  rxCurBufferDesc = &rxBufferDesc[0];
287 
288  //Starting address of TX descriptor table
289  ETHTXST = KVA_TO_PA(&txBufferDesc[0]);
290  //Starting address of RX descriptor table
291  ETHRXST = KVA_TO_PA(&rxBufferDesc[0]);
292  //Set receive buffer size
293  ETHCON2 = PIC32MX_ETH_RX_BUFFER_SIZE;
294 }
295 
296 
297 /**
298  * @brief PIC32MX Ethernet MAC timer handler
299  *
300  * This routine is periodically called by the TCP/IP stack to handle periodic
301  * operations such as polling the link state
302  *
303  * @param[in] interface Underlying network interface
304  **/
305 
306 void pic32mxEthTick(NetInterface *interface)
307 {
308  //Valid Ethernet PHY or switch driver?
309  if(interface->phyDriver != NULL)
310  {
311  //Handle periodic operations
312  interface->phyDriver->tick(interface);
313  }
314  else if(interface->switchDriver != NULL)
315  {
316  //Handle periodic operations
317  interface->switchDriver->tick(interface);
318  }
319  else
320  {
321  //Just for sanity
322  }
323 }
324 
325 
326 /**
327  * @brief Enable interrupts
328  * @param[in] interface Underlying network interface
329  **/
330 
332 {
333  //Enable Ethernet MAC interrupts
334  IEC1SET = _IEC1_ETHIE_MASK;
335 
336  //Valid Ethernet PHY or switch driver?
337  if(interface->phyDriver != NULL)
338  {
339  //Enable Ethernet PHY interrupts
340  interface->phyDriver->enableIrq(interface);
341  }
342  else if(interface->switchDriver != NULL)
343  {
344  //Enable Ethernet switch interrupts
345  interface->switchDriver->enableIrq(interface);
346  }
347  else
348  {
349  //Just for sanity
350  }
351 }
352 
353 
354 /**
355  * @brief Disable interrupts
356  * @param[in] interface Underlying network interface
357  **/
358 
360 {
361  //Disable Ethernet MAC interrupts
362  IEC1CLR = _IEC1_ETHIE_MASK;
363 
364  //Valid Ethernet PHY or switch driver?
365  if(interface->phyDriver != NULL)
366  {
367  //Disable Ethernet PHY interrupts
368  interface->phyDriver->disableIrq(interface);
369  }
370  else if(interface->switchDriver != NULL)
371  {
372  //Disable Ethernet switch interrupts
373  interface->switchDriver->disableIrq(interface);
374  }
375  else
376  {
377  //Just for sanity
378  }
379 }
380 
381 
382 /**
383  * @brief PIC32MX Ethernet MAC interrupt service routine
384  **/
385 
387 {
388  bool_t flag;
389  uint32_t status;
390 
391  //Interrupt service routine prologue
392  osEnterIsr();
393 
394  //This flag will be set if a higher priority task must be woken
395  flag = FALSE;
396 
397  //Read interrupt status register
398  status = ETHIRQ;
399 
400  //Packet transmitted?
401  if((status & _ETHIRQ_TXDONE_MASK) != 0)
402  {
403  //Clear TXDONE interrupt flag
404  ETHIRQCLR = _ETHIRQ_TXDONE_MASK;
405 
406  //Check whether the TX buffer is available for writing
407  if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) == 0)
408  {
409  //Notify the TCP/IP stack that the transmitter is ready to send
410  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
411  }
412  }
413 
414  //Packet received?
415  if((status & _ETHIRQ_PKTPEND_MASK) != 0)
416  {
417  //Disable PKTPEND interrupt
418  ETHIENCLR = _ETHIEN_PKTPENDIE_MASK;
419 
420  //Set event flag
421  nicDriverInterface->nicEvent = TRUE;
422  //Notify the TCP/IP stack of the event
423  flag |= osSetEventFromIsr(&netEvent);
424  }
425 
426  //Clear ETHIF interrupt flag before exiting the service routine
427  IFS1CLR = _IFS1_ETHIF_MASK;
428 
429  //Interrupt service routine epilogue
430  osExitIsr(flag);
431 }
432 
433 
434 /**
435  * @brief PIC32MX Ethernet MAC event handler
436  * @param[in] interface Underlying network interface
437  **/
438 
440 {
441  error_t error;
442 
443  //Packet received?
444  if((ETHIRQ & _ETHIRQ_PKTPEND_MASK) != 0)
445  {
446  //Process all pending packets
447  do
448  {
449  //Read incoming packet
450  error = pic32mxEthReceivePacket(interface);
451 
452  //No more data in the receive buffer?
453  } while(error != ERROR_BUFFER_EMPTY);
454  }
455 
456  //Re-enable PKTPEND interrupt
457  ETHIENSET = _ETHIEN_PKTPENDIE_MASK;
458 }
459 
460 
461 /**
462  * @brief Send a packet
463  * @param[in] interface Underlying network interface
464  * @param[in] buffer Multi-part buffer containing the data to send
465  * @param[in] offset Offset to the first data byte
466  * @param[in] ancillary Additional options passed to the stack along with
467  * the packet
468  * @return Error code
469  **/
470 
472  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
473 {
474  size_t length;
475  uint32_t value;
476 
477  //Retrieve the length of the packet
478  length = netBufferGetLength(buffer) - offset;
479 
480  //Check the frame length
482  {
483  //The transmitter can accept another packet
484  osSetEvent(&interface->nicTxEvent);
485  //Report an error
486  return ERROR_INVALID_LENGTH;
487  }
488 
489  //Make sure the current buffer is available for writing
490  if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) != 0)
491  {
492  return ERROR_FAILURE;
493  }
494 
495  //Copy user data to the transmit buffer
496  netBufferRead(PA_TO_KVA1(txCurBufferDesc->address), buffer, offset, length);
497 
498  //Write the number of bytes to send
499  value = (length << 16) & ETH_TX_CTRL_BYTE_COUNT;
500  //Set SOP and EOP flags since the data fits in a single buffer
502  //Give the ownership of the descriptor to the DMA
503  txCurBufferDesc->control = value | ETH_TX_CTRL_EOWN;
504 
505  //Set TXRTS bit to start the transmission
506  ETHCON1SET = _ETHCON1_TXRTS_MASK;
507 
508  //Point to the next descriptor in the list
509  txCurBufferDesc = PA_TO_KVA1(txCurBufferDesc->next);
510 
511  //Check whether the next buffer is available for writing
512  if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) == 0)
513  {
514  //The transmitter can accept another packet
515  osSetEvent(&interface->nicTxEvent);
516  }
517 
518  //Data successfully written
519  return NO_ERROR;
520 }
521 
522 
523 /**
524  * @brief Receive a packet
525  * @param[in] interface Underlying network interface
526  * @return Error code
527  **/
528 
530 {
531  static uint32_t temp[PIC32MX_ETH_RX_BUFFER_SIZE / 4];
532  error_t error;
533  size_t n;
534  NetRxAncillary ancillary;
535 
536  //Current buffer available for reading?
537  if((rxCurBufferDesc->control & ETH_RX_CTRL_EOWN) == 0)
538  {
539  //SOP and EOP flags should be set
540  if((rxCurBufferDesc->control & ETH_RX_CTRL_SOP) != 0 &&
541  (rxCurBufferDesc->control & ETH_RX_CTRL_EOP) != 0)
542  {
543  //Make sure no error occurred
544  if((rxCurBufferDesc->status2 & ETH_RX_STATUS2_OK) != 0)
545  {
546  //Retrieve the length of the frame
547  n = (rxCurBufferDesc->control & ETH_RX_CTRL_BYTE_COUNT) >> 16;
548  //Limit the number of data to read
550 
551  //Copy data from the receive buffer
552  osMemcpy(temp, PA_TO_KVA1(rxCurBufferDesc->address), n);
553 
554  //Additional options can be passed to the stack along with the packet
555  ancillary = NET_DEFAULT_RX_ANCILLARY;
556 
557  //Pass the packet to the upper layer
558  nicProcessPacket(interface, (uint8_t *) temp, n, &ancillary);
559 
560  //Valid packet received
561  error = NO_ERROR;
562  }
563  else
564  {
565  //The received packet contains an error
566  error = ERROR_INVALID_PACKET;
567  }
568  }
569  else
570  {
571  //The packet is not valid
572  error = ERROR_INVALID_PACKET;
573  }
574 
575  //Give the ownership of the descriptor back to the DMA
576  rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
577 
578  //Point to the next descriptor in the list
579  rxCurBufferDesc = PA_TO_KVA1(rxCurBufferDesc->next);
580 
581  //Once software processes a received packet, it should write the BUFCDEC
582  //bit in order to decrement the packet buffer count BUFCNT
583  ETHCON1SET = _ETHCON1_BUFCDEC_MASK;
584  }
585  else
586  {
587  //No more data in the receive buffer
588  error = ERROR_BUFFER_EMPTY;
589  }
590 
591  //Return status code
592  return error;
593 }
594 
595 
596 /**
597  * @brief Configure MAC address filtering
598  * @param[in] interface Underlying network interface
599  * @return Error code
600  **/
601 
603 {
604  uint_t i;
605  uint_t k;
606  uint32_t crc;
607  uint32_t hashTable[2];
608  MacFilterEntry *entry;
609 
610  //Debug message
611  TRACE_DEBUG("Updating MAC filter...\r\n");
612 
613  //Clear hash table
614  hashTable[0] = 0;
615  hashTable[1] = 0;
616 
617  //The MAC address filter contains the list of MAC addresses to accept
618  //when receiving an Ethernet frame
619  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
620  {
621  //Point to the current entry
622  entry = &interface->macAddrFilter[i];
623 
624  //Valid entry?
625  if(entry->refCount > 0)
626  {
627  //Compute CRC over the current MAC address
628  crc = pic32mxEthCalcCrc(&entry->addr, sizeof(MacAddr));
629  //Calculate the corresponding index in the table
630  k = (crc >> 23) & 0x3F;
631  //Update hash table contents
632  hashTable[k / 32] |= (1 << (k % 32));
633  }
634  }
635 
636  //Write the hash table
637  ETHHT0 = hashTable[0];
638  ETHHT1 = hashTable[1];
639 
640  //Debug message
641  TRACE_DEBUG(" ETHHT0 = %08" PRIX32 "\r\n", ETHHT0);
642  TRACE_DEBUG(" ETHHT1 = %08" PRIX32 "\r\n", ETHHT1);
643 
644  //Successful processing
645  return NO_ERROR;
646 }
647 
648 
649 /**
650  * @brief Adjust MAC configuration parameters for proper operation
651  * @param[in] interface Underlying network interface
652  * @return Error code
653  **/
654 
656 {
657  //Check current operating speed
658  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
659  {
660  //100BASE-TX operation mode
661  EMAC1SUPPSET = _EMAC1SUPP_SPEEDRMII_MASK;
662  }
663  else
664  {
665  //10BASE-T operation mode
666  EMAC1SUPPCLR = _EMAC1SUPP_SPEEDRMII_MASK;
667  }
668 
669  //Half-duplex or full-duplex mode?
670  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
671  {
672  //Configure FULLDPLX bit to match the current duplex mode
673  EMAC1CFG2SET = _EMAC1CFG2_FULLDPLX_MASK;
674  //Configure the Back-to-Back Inter-Packet Gap register
675  EMAC1IPGT = 0x15;
676  }
677  else
678  {
679  //Configure FULLDPLX bit to match the current duplex mode
680  EMAC1CFG2CLR = _EMAC1CFG2_FULLDPLX_MASK;
681  //Configure the Back-to-Back Inter-Packet Gap register
682  EMAC1IPGT = 0x12;
683  }
684 
685  //Successful processing
686  return NO_ERROR;
687 }
688 
689 
690 /**
691  * @brief Write PHY register
692  * @param[in] opcode Access type (2 bits)
693  * @param[in] phyAddr PHY address (5 bits)
694  * @param[in] regAddr Register address (5 bits)
695  * @param[in] data Register value
696  **/
697 
698 void pic32mxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
699  uint8_t regAddr, uint16_t data)
700 {
701  //Valid opcode?
702  if(opcode == SMI_OPCODE_WRITE)
703  {
704  //Set PHY address and register address
705  EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
706  //Start a write operation
707  EMAC1MWTD = data & _EMAC1MWTD_MWTD_MASK;
708 
709  //Wait for busy bit to be set
710  __asm__ __volatile__ ("nop;");
711  __asm__ __volatile__ ("nop;");
712  __asm__ __volatile__ ("nop;");
713 
714  //Wait for the write to complete
715  while((EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK) != 0)
716  {
717  }
718  }
719  else
720  {
721  //The MAC peripheral only supports standard Clause 22 opcodes
722  }
723 }
724 
725 
726 /**
727  * @brief Read PHY register
728  * @param[in] opcode Access type (2 bits)
729  * @param[in] phyAddr PHY address (5 bits)
730  * @param[in] regAddr Register address (5 bits)
731  * @return Register value
732  **/
733 
734 uint16_t pic32mxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
735  uint8_t regAddr)
736 {
737  uint16_t data;
738 
739  //Valid opcode?
740  if(opcode == SMI_OPCODE_READ)
741  {
742  //Set PHY address and register address
743  EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
744  //Start a read operation
745  EMAC1MCMD = _EMAC1MCMD_READ_MASK;
746 
747  //Wait for busy bit to be set
748  __asm__ __volatile__ ("nop;");
749  __asm__ __volatile__ ("nop;");
750  __asm__ __volatile__ ("nop;");
751 
752  //Wait for the read to complete
753  while((EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK) != 0)
754  {
755  }
756 
757  //Clear command register
758  EMAC1MCMD = 0;
759  //Get register value
760  data = EMAC1MRDD & _EMAC1MRDD_MRDD_MASK;
761  }
762  else
763  {
764  //The MAC peripheral only supports standard Clause 22 opcodes
765  data = 0;
766  }
767 
768  //Return the value of the PHY register
769  return data;
770 }
771 
772 
773 /**
774  * @brief CRC calculation
775  * @param[in] data Pointer to the data over which to calculate the CRC
776  * @param[in] length Number of bytes to process
777  * @return Resulting CRC value
778  **/
779 
780 uint32_t pic32mxEthCalcCrc(const void *data, size_t length)
781 {
782  uint_t i;
783  uint_t j;
784  uint32_t crc;
785  const uint8_t *p;
786 
787  //Point to the data over which to calculate the CRC
788  p = (uint8_t *) data;
789  //CRC preset value
790  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) != 0)
800  {
801  crc = (crc << 1) ^ 0x04C11DB7;
802  }
803  else
804  {
805  crc = crc << 1;
806  }
807  }
808  }
809 
810  //Return CRC value
811  return crc;
812 }
#define rxBuffer
#define txBuffer
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint8_t opcode
Definition: dns_common.h:188
error_t
Error codes.
Definition: error.h:43
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PACKET
Definition: error.h:140
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:944
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
MacAddr
Definition: ethernet.h:195
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
uint16_t regAddr
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netEvent
Definition: net_legacy.h:196
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
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:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
#define SMI_OPCODE_WRITE
Definition: nic.h:66
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define SMI_OPCODE_READ
Definition: nic.h:67
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define osEnterIsr()
#define osExitIsr(flag)
error_t pic32mxEthReceivePacket(NetInterface *interface)
Receive a packet.
error_t pic32mxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void pic32mxEthTick(NetInterface *interface)
PIC32MX Ethernet MAC timer handler.
void pic32mxEthEventHandler(NetInterface *interface)
PIC32MX Ethernet MAC event handler.
void pic32mxEthInitBufferDesc(NetInterface *interface)
Initialize DMA descriptor lists.
uint16_t pic32mxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
error_t pic32mxEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void pic32mxEthDisableIrq(NetInterface *interface)
Disable interrupts.
void pic32mxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void pic32mxEthIrqHandler(void)
PIC32MX Ethernet MAC interrupt service routine.
error_t pic32mxEthInit(NetInterface *interface)
PIC32MX Ethernet MAC initialization.
void pic32mxEthEnableIrq(NetInterface *interface)
Enable interrupts.
error_t pic32mxEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
__weak_func void pic32mxEthInitGpio(NetInterface *interface)
GPIO configuration.
const NicDriver pic32mxEthDriver
PIC32MX Ethernet MAC driver.
uint32_t pic32mxEthCalcCrc(const void *data, size_t length)
CRC calculation.
PIC32MX Ethernet MAC driver.
#define ETH_TX_CTRL_EOWN
#define PIC32MX_ETH_IRQ_SUB_PRIORITY
#define ETH_RX_CTRL_BYTE_COUNT
#define PIC32MX_ETH_RX_BUFFER_COUNT
#define ETH_RX_CTRL_SOP
#define PIC32MX_ETH_TX_BUFFER_SIZE
#define ETH_TX_CTRL_NPV
#define ETH_RX_CTRL_EOWN
#define ETH_TX_CTRL_SOP
#define ETH_RX_STATUS2_OK
#define PIC32MX_ETH_TX_BUFFER_COUNT
#define ETH_TX_CTRL_EOP
#define ETH_RX_CTRL_NPV
#define PIC32MX_ETH_RX_BUFFER_SIZE
#define _EMAC1MCFG_CLKSEL_DIV40
#define PIC32MX_ETH_IRQ_PRIORITY
#define ETH_TX_CTRL_BYTE_COUNT
#define ETH_RX_CTRL_EOP
MAC filter table entry.
Definition: ethernet.h:262
MacAddr addr
MAC address.
Definition: ethernet.h:263
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
RX buffer descriptor.
TX buffer descriptor.
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369