pic32mz_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file pic32mz_eth_driver.c
3  * @brief PIC32MZ 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 <p32xxxx.h>
34 #include <sys/kmem.h>
35 #include "core/net.h"
37 #include "debug.h"
38 
39 //Underlying network interface
40 static NetInterface *nicDriverInterface;
41 
42 //Transmit buffer
44  __attribute__((aligned(4)));
45 //Receive buffer
47  __attribute__((aligned(4)));
48 //Transmit buffer descriptors
50  __attribute__((aligned(4)));
51 //Receive buffer descriptors
53  __attribute__((aligned(4)));
54 
55 //Pointer to the current TX buffer descriptor
56 static Pic32mzTxBufferDesc *txCurBufferDesc;
57 //Pointer to the current RX buffer descriptor
58 static Pic32mzRxBufferDesc *rxCurBufferDesc;
59 
60 
61 /**
62  * @brief PIC32MZ Ethernet MAC driver
63  **/
64 
66 {
68  ETH_MTU,
79  TRUE,
80  TRUE,
81  TRUE,
82  FALSE
83 };
84 
85 
86 /**
87  * @brief PIC32MZ Ethernet MAC initialization
88  * @param[in] interface Underlying network interface
89  * @return Error code
90  **/
91 
93 {
94  error_t error;
95 
96  //Debug message
97  TRACE_INFO("Initializing PIC32MZ Ethernet MAC...\r\n");
98 
99  //Save underlying network interface
100  nicDriverInterface = interface;
101 
102  //GPIO configuration
103  pic32mzEthInitGpio(interface);
104 
105  //Disable Ethernet interrupts
106  IEC4CLR = _IEC4_ETHIE_MASK;
107  //Turn the Ethernet controller off
108  ETHCON1CLR = _ETHCON1_ON_MASK | _ETHCON1_TXRTS_POSITION | _ETHCON1_RXEN_MASK;
109 
110  //Wait activity abort by polling the ETHBUSY bit
111  while(ETHSTAT & _ETHSTAT_ETHBUSY_MASK);
112 
113  //Enable the Ethernet controller by setting the ON bit
114  ETHCON1SET = _ETHCON1_ON_MASK;
115 
116  //Clear Ethernet interrupt flag
117  IFS4CLR = _IFS4_ETHIF_MASK;
118  //Disable any Ethernet controller interrupt generation
119  ETHIEN = 0;
120  ETHIRQ = 0;
121  //Clear the TX and RX start addresses
122  ETHTXST = 0;
123  ETHRXST = 0;
124 
125  //Reset the MAC using SOFTRESET
126  EMAC1CFG1SET = _EMAC1CFG1_SOFTRESET_MASK;
127  EMAC1CFG1CLR = _EMAC1CFG1_SOFTRESET_MASK;
128 
129  //Reset the RMII module
130  EMAC1SUPPSET = _EMAC1SUPP_RESETRMII_MASK;
131  EMAC1SUPPCLR = _EMAC1SUPP_RESETRMII_MASK;
132 
133  //Issue an MIIM block reset by setting the RESETMGMT bit
134  EMAC1MCFGSET = _EMAC1MCFG_RESETMGMT_MASK;
135  EMAC1MCFGCLR = _EMAC1MCFG_RESETMGMT_MASK;
136 
137  //Select the proper divider for the MDC clock
138  EMAC1MCFG = _EMAC1MCFG_CLKSEL_DIV50;
139 
140  //PHY transceiver initialization
141  error = interface->phyDriver->init(interface);
142  //Failed to initialize PHY transceiver?
143  if(error)
144  return error;
145 
146  //Optionally set the station MAC address
147  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
148  {
149  //Use the factory preprogrammed station address
150  interface->macAddr.w[0] = EMAC1SA2;
151  interface->macAddr.w[1] = EMAC1SA1;
152  interface->macAddr.w[2] = EMAC1SA0;
153 
154  //Generate the 64-bit interface identifier
155  macAddrToEui64(&interface->macAddr, &interface->eui64);
156  }
157  else
158  {
159  //Override the factory preprogrammed address
160  EMAC1SA0 = interface->macAddr.w[2];
161  EMAC1SA1 = interface->macAddr.w[1];
162  EMAC1SA2 = interface->macAddr.w[0];
163  }
164 
165  //Initialize hash table
166  ETHHT0 = 0;
167  ETHHT1 = 0;
168 
169  //Configure the receive filter
170  ETHRXFC = _ETHRXFC_HTEN_MASK | _ETHRXFC_CRCOKEN_MASK |
171  _ETHRXFC_RUNTEN_MASK | _ETHRXFC_UCEN_MASK | _ETHRXFC_BCEN_MASK;
172 
173  //Disable flow control
174  EMAC1CFG1 = _EMAC1CFG1_RXENABLE_MASK;
175  //Automatic padding and CRC generation
176  EMAC1CFG2 = _EMAC1CFG2_PADENABLE_MASK | _EMAC1CFG2_CRCENABLE_MASK;
177  //Set the maximum frame length
178  EMAC1MAXF = 1518;
179 
180  //Initialize DMA descriptor lists
181  pic32mzEthInitBufferDesc(interface);
182 
183  //Enable desired interrupts
184  ETHIENSET = _ETHIEN_PKTPENDIE_MASK | _ETHIEN_TXDONEIE_MASK;
185 
186  //Set interrupt priority
187  IPC38CLR = _IPC38_ETHIP_MASK;
188  IPC38SET = (PIC32MZ_ETH_IRQ_PRIORITY << _IPC38_ETHIP_POSITION);
189  //Set interrupt subpriority
190  IPC38CLR = _IPC38_ETHIS_MASK;
191  IPC38SET = (PIC32MZ_ETH_IRQ_SUB_PRIORITY << _IPC38_ETHIS_POSITION);
192 
193  //Enable the reception by setting the RXEN bit
194  ETHCON1SET = _ETHCON1_RXEN_MASK;
195 
196  //Accept any packets from the upper layer
197  osSetEvent(&interface->nicTxEvent);
198 
199  //Successful initialization
200  return NO_ERROR;
201 }
202 
203 
204 //PIC32MZ EC Starter Kit, PIC32MZ EF Starter Kit, PIC32MZ EF Curiosity
205 //or IoT Ethernet Kit?
206 #if defined(USE_PIC32MZ_EC_STARTER_KIT) || defined(USE_PIC32MZ_EF_STARTER_KIT) || \
207  defined(USE_PIC32MZ_EF_CURIOSITY) || defined(USE_IOT_ETHERNET_KIT)
208 
209 /**
210  * @brief GPIO configuration
211  * @param[in] interface Underlying network interface
212  **/
213 
214 void pic32mzEthInitGpio(NetInterface *interface)
215 {
216 //PIC32MZ EC Starter Kit or PIC32MZ EF Starter Kit?
217 #if defined(USE_PIC32MZ_EC_STARTER_KIT) || defined(USE_PIC32MZ_EF_STARTER_KIT)
218  //Disable analog pad on ETXD0 (AN35/RJ8)
219  ANSELJCLR = _ANSELJ_ANSJ8_MASK;
220  //Disable analog pad on ETXD1 (AN36/RJ9)
221  ANSELJCLR = _ANSELJ_ANSJ9_MASK;
222  //Disable analog pad on EREFCLK (AN37/RJ11)
223  ANSELJCLR = _ANSELJ_ANSJ11_MASK;
224  //Disable analog pad on ERXERR (AN40/RH4)
225  ANSELHCLR = _ANSELH_ANSH4_MASK;
226  //Disable analog pad on ERXD1 (AN41/RH5)
227  ANSELHCLR = _ANSELH_ANSH5_MASK;
228 
229 //PIC32MZ EF Curiosity?
230 #elif defined(USE_PIC32MZ_EF_CURIOSITY)
231  //Disable analog pad on ERXERR (AN6/RB11)
232  ANSELBCLR = _ANSELB_ANSB11_MASK;
233  //Disable analog pad on ERXD0 (AN7/RB12)
234  ANSELBCLR = _ANSELB_ANSB12_MASK;
235  //Disable analog pad on ERXD1 (AN8/RB13)
236  ANSELBCLR = _ANSELB_ANSB13_MASK;
237  //Disable analog pad on ERXDV (AN12/RG8)
238  ANSELGCLR = _ANSELG_ANSG8_MASK;
239  //Disable analog pad on EREFCLK (AN11/RG9)
240  ANSELGCLR = _ANSELG_ANSG9_MASK;
241 
242 //IoT Ethernet Kit?
243 #elif defined(USE_IOT_ETHERNET_KIT)
244  //Disable analog pad on ERXERR (AN18/RE4)
245  ANSELECLR = _ANSELE_ANSE4_MASK;
246  //Disable analog pad on ETXEN (AN17/RE5)
247  ANSELECLR = _ANSELE_ANSE5_MASK;
248  //Disable analog pad on ETXD0 (AN16/RE6)
249  ANSELECLR = _ANSELE_ANSE6_MASK;
250  //Disable analog pad on ETXD1 (AN15/RE7)
251  ANSELECLR = _ANSELE_ANSE7_MASK;
252 #endif
253 }
254 
255 #endif
256 
257 
258 /**
259  * @brief Initialize DMA descriptor lists
260  * @param[in] interface Underlying network interface
261  **/
262 
264 {
265  uint_t i;
266 
267  //Initialize TX descriptor list
268  for(i = 0; i < PIC32MZ_ETH_TX_BUFFER_COUNT; i++)
269  {
270  //Point to the current descriptor
271  txCurBufferDesc = KVA0_TO_KVA1(&txBufferDesc[i]);
272 
273  //Use linked list rather than linear list
274  txCurBufferDesc->control = ETH_TX_CTRL_NPV;
275  //Transmit buffer address
276  txCurBufferDesc->address = (uint32_t) KVA_TO_PA(txBuffer[i]);
277  //Transmit status vector
278  txCurBufferDesc->status1 = 0;
279  txCurBufferDesc->status2 = 0;
280  //Next descriptor address
281  txCurBufferDesc->next = (uint32_t) KVA_TO_PA(&txBufferDesc[i + 1]);
282  }
283 
284  //The last descriptor is chained to the first entry
285  txCurBufferDesc->next = (uint32_t) KVA_TO_PA(&txBufferDesc[0]);
286  //Point to the very first descriptor
287  txCurBufferDesc = KVA0_TO_KVA1(&txBufferDesc[0]);
288 
289  //Initialize RX descriptor list
290  for(i = 0; i < PIC32MZ_ETH_RX_BUFFER_COUNT; i++)
291  {
292  //Point to the current descriptor
293  rxCurBufferDesc = KVA0_TO_KVA1(&rxBufferDesc[i]);
294 
295  //The descriptor is initially owned by the DMA
296  rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
297  //Receive buffer address
298  rxCurBufferDesc->address = (uint32_t) KVA_TO_PA(rxBuffer[i]);
299  //Receive status vector
300  rxCurBufferDesc->status1 = 0;
301  rxCurBufferDesc->status2 = 0;
302  //Next descriptor address
303  rxCurBufferDesc->next = (uint32_t) KVA_TO_PA(&rxBufferDesc[i + 1]);
304  }
305 
306  //The last descriptor is chained to the first entry
307  rxCurBufferDesc->next = (uint32_t) KVA_TO_PA(&rxBufferDesc[0]);
308  //Point to the very first descriptor
309  rxCurBufferDesc = KVA0_TO_KVA1(&rxBufferDesc[0]);
310 
311  //Starting address of TX descriptor table
312  ETHTXST = (uint32_t) KVA_TO_PA(&txBufferDesc[0]);
313  //Starting address of RX descriptor table
314  ETHRXST = (uint32_t) KVA_TO_PA(&rxBufferDesc[0]);
315  //Set receive buffer size
316  ETHCON2 = PIC32MZ_ETH_RX_BUFFER_SIZE;
317 }
318 
319 
320 /**
321  * @brief PIC32MZ Ethernet MAC timer handler
322  *
323  * This routine is periodically called by the TCP/IP stack to
324  * handle periodic operations such as polling the link state
325  *
326  * @param[in] interface Underlying network interface
327  **/
328 
329 void pic32mzEthTick(NetInterface *interface)
330 {
331  //Handle periodic operations
332  interface->phyDriver->tick(interface);
333 }
334 
335 
336 /**
337  * @brief Enable interrupts
338  * @param[in] interface Underlying network interface
339  **/
340 
342 {
343  //Enable Ethernet MAC interrupts
344  IEC4SET = _IEC4_ETHIE_MASK;
345  //Enable Ethernet PHY interrupts
346  interface->phyDriver->enableIrq(interface);
347 }
348 
349 
350 /**
351  * @brief Disable interrupts
352  * @param[in] interface Underlying network interface
353  **/
354 
356 {
357  //Disable Ethernet MAC interrupts
358  IEC4CLR = _IEC4_ETHIE_MASK;
359  //Disable Ethernet PHY interrupts
360  interface->phyDriver->disableIrq(interface);
361 }
362 
363 
364 /**
365  * @brief PIC32MZ Ethernet MAC interrupt service routine
366  **/
367 
369 {
370  bool_t flag;
371  uint32_t status;
372 
373  //Enter interrupt service routine
374  osEnterIsr();
375 
376  //This flag will be set if a higher priority task must be woken
377  flag = FALSE;
378 
379  //Read interrupt status register
380  status = ETHIRQ;
381 
382  //A packet has been transmitted?
383  if(status & _ETHIRQ_TXDONE_MASK)
384  {
385  //Clear TXDONE interrupt flag
386  ETHIRQCLR = _ETHIRQ_TXDONE_MASK;
387 
388  //Check whether the TX buffer is available for writing
389  if(!(txCurBufferDesc->control & ETH_TX_CTRL_EOWN))
390  {
391  //Notify the TCP/IP stack that the transmitter is ready to send
392  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
393  }
394  }
395 
396  //A packet has been received?
397  if(status & _ETHIRQ_PKTPEND_MASK)
398  {
399  //Disable PKTPEND interrupt
400  ETHIENCLR = _ETHIEN_PKTPENDIE_MASK;
401 
402  //Set event flag
403  nicDriverInterface->nicEvent = TRUE;
404  //Notify the TCP/IP stack of the event
405  flag |= osSetEventFromIsr(&netEvent);
406  }
407 
408  //Clear ETHIF interrupt flag before exiting the service routine
409  IFS4CLR = _IFS4_ETHIF_MASK;
410 
411  //Leave interrupt service routine
412  osExitIsr(flag);
413 }
414 
415 
416 /**
417  * @brief PIC32MZ Ethernet MAC event handler
418  * @param[in] interface Underlying network interface
419  **/
420 
422 {
423  error_t error;
424 
425  //Packet received?
426  if(ETHIRQ & _ETHIRQ_PKTPEND_MASK)
427  {
428  //Process all pending packets
429  do
430  {
431  //Read incoming packet
432  error = pic32mzEthReceivePacket(interface);
433 
434  //No more data in the receive buffer?
435  } while(error != ERROR_BUFFER_EMPTY);
436  }
437 
438  //Re-enable PKTPEND interrupt
439  ETHIENSET = _ETHIEN_PKTPENDIE_MASK;
440 }
441 
442 
443 /**
444  * @brief Send a packet
445  * @param[in] interface Underlying network interface
446  * @param[in] buffer Multi-part buffer containing the data to send
447  * @param[in] offset Offset to the first data byte
448  * @return Error code
449  **/
450 
452  const NetBuffer *buffer, size_t offset)
453 {
454  size_t length;
455  uint32_t value;
456 
457  //Retrieve the length of the packet
458  length = netBufferGetLength(buffer) - offset;
459 
460  //Check the frame length
462  {
463  //The transmitter can accept another packet
464  osSetEvent(&interface->nicTxEvent);
465  //Report an error
466  return ERROR_INVALID_LENGTH;
467  }
468 
469  //Make sure the current buffer is available for writing
470  if(txCurBufferDesc->control & ETH_TX_CTRL_EOWN)
471  return ERROR_FAILURE;
472 
473  //Copy user data to the transmit buffer
474  netBufferRead(PA_TO_KVA1(txCurBufferDesc->address), buffer, offset, length);
475 
476  //Write the number of bytes to send
477  value = (length << 16) & ETH_TX_CTRL_BYTE_COUNT;
478  //Set SOP and EOP flags since the data fits in a single buffer
480  //Give the ownership of the descriptor to the DMA
481  txCurBufferDesc->control = value | ETH_TX_CTRL_EOWN;
482 
483  //Set TXRTS bit to start the transmission
484  ETHCON1SET = _ETHCON1_TXRTS_MASK;
485 
486  //Point to the next descriptor in the list
487  txCurBufferDesc = PA_TO_KVA1(txCurBufferDesc->next);
488 
489  //Check whether the next buffer is available for writing
490  if(!(txCurBufferDesc->control & ETH_TX_CTRL_EOWN))
491  {
492  //The transmitter can accept another packet
493  osSetEvent(&interface->nicTxEvent);
494  }
495 
496  //Data successfully written
497  return NO_ERROR;
498 }
499 
500 
501 /**
502  * @brief Receive a packet
503  * @param[in] interface Underlying network interface
504  * @return Error code
505  **/
506 
508 {
509  static uint8_t temp[PIC32MZ_ETH_RX_BUFFER_SIZE];
510  error_t error;
511  size_t n;
512 
513  //The current buffer is available for reading?
514  if(!(rxCurBufferDesc->control & ETH_RX_CTRL_EOWN))
515  {
516  //SOP and EOP flags should be set
517  if((rxCurBufferDesc->control & ETH_RX_CTRL_SOP) &&
518  (rxCurBufferDesc->control & ETH_RX_CTRL_EOP))
519  {
520  //Make sure no error occurred
521  if(rxCurBufferDesc->status2 & ETH_RX_STATUS2_OK)
522  {
523  //Retrieve the length of the frame
524  n = (rxCurBufferDesc->control & ETH_RX_CTRL_BYTE_COUNT) >> 16;
525  //Limit the number of data to read
527 
528  //Copy data from the receive buffer
529  memcpy(temp, PA_TO_KVA1(rxCurBufferDesc->address), n);
530 
531  //Pass the packet to the upper layer
532  nicProcessPacket(interface, temp, n);
533 
534  //Valid packet received
535  error = NO_ERROR;
536  }
537  else
538  {
539  //The received packet contains an error
540  error = ERROR_INVALID_PACKET;
541  }
542  }
543  else
544  {
545  //The packet is not valid
546  error = ERROR_INVALID_PACKET;
547  }
548 
549  //Give the ownership of the descriptor back to the DMA
550  rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
551 
552  //Point to the next descriptor in the list
553  rxCurBufferDesc = PA_TO_KVA1(rxCurBufferDesc->next);
554 
555  //Decrement BUFCNT counter
556  ETHCON1SET = _ETHCON1_BUFCDEC_MASK;
557  }
558  else
559  {
560  //No more data in the receive buffer
561  error = ERROR_BUFFER_EMPTY;
562  }
563 
564  //Return status code
565  return error;
566 }
567 
568 
569 /**
570  * @brief Configure MAC address filtering
571  * @param[in] interface Underlying network interface
572  * @return Error code
573  **/
574 
576 {
577  uint_t i;
578  uint_t k;
579  uint32_t crc;
580  uint32_t hashTable[2];
581  MacFilterEntry *entry;
582 
583  //Debug message
584  TRACE_DEBUG("Updating PIC32MZ hash table...\r\n");
585 
586  //Clear hash table
587  hashTable[0] = 0;
588  hashTable[1] = 0;
589 
590  //The MAC address filter contains the list of MAC addresses to accept
591  //when receiving an Ethernet frame
592  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
593  {
594  //Point to the current entry
595  entry = &interface->macAddrFilter[i];
596 
597  //Valid entry?
598  if(entry->refCount > 0)
599  {
600  //Compute CRC over the current MAC address
601  crc = pic32mzEthCalcCrc(&entry->addr, sizeof(MacAddr));
602  //Calculate the corresponding index in the table
603  k = (crc >> 23) & 0x3F;
604  //Update hash table contents
605  hashTable[k / 32] |= (1 << (k % 32));
606  }
607  }
608 
609  //Write the hash table
610  ETHHT0 = hashTable[0];
611  ETHHT1 = hashTable[1];
612 
613  //Debug message
614  TRACE_DEBUG(" ETHHT0 = %08" PRIX32 "\r\n", ETHHT0);
615  TRACE_DEBUG(" ETHHT1 = %08" PRIX32 "\r\n", ETHHT1);
616 
617  //Successful processing
618  return NO_ERROR;
619 }
620 
621 
622 /**
623  * @brief Adjust MAC configuration parameters for proper operation
624  * @param[in] interface Underlying network interface
625  * @return Error code
626  **/
627 
629 {
630  //Check current operating speed
631  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
632  {
633  //100BASE-TX operation mode
634  EMAC1SUPPSET = _EMAC1SUPP_SPEEDRMII_MASK;
635  }
636  else
637  {
638  //10BASE-T operation mode
639  EMAC1SUPPCLR = _EMAC1SUPP_SPEEDRMII_MASK;
640  }
641 
642  //Half-duplex or full-duplex mode?
643  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
644  {
645  //Configure FULLDPLX bit to match the current duplex mode
646  EMAC1CFG2SET = _EMAC1CFG2_FULLDPLX_MASK;
647  //Configure the Back-to-Back Inter-Packet Gap register
648  EMAC1IPGT = 0x15;
649  }
650  else
651  {
652  //Configure FULLDPLX bit to match the current duplex mode
653  EMAC1CFG2CLR = _EMAC1CFG2_FULLDPLX_MASK;
654  //Configure the Back-to-Back Inter-Packet Gap register
655  EMAC1IPGT = 0x12;
656  }
657 
658  //Successful processing
659  return NO_ERROR;
660 }
661 
662 
663 /**
664  * @brief Write PHY register
665  * @param[in] phyAddr PHY address
666  * @param[in] regAddr Register address
667  * @param[in] data Register value
668  **/
669 
670 void pic32mzEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
671 {
672  uint_t i;
673 
674  //Set PHY address and register address
675  EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
676  //Start a write operation
677  EMAC1MWTD = data & _EMAC1MWTD_MWTD_MASK;
678 
679  //Wait for busy bit to be set
680  for(i = 0; i < 16; i++)
681  __asm__ __volatile__ ("nop;");
682 
683  //Wait for the write to complete
684  while(EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK);
685 }
686 
687 
688 /**
689  * @brief Read PHY register
690  * @param[in] phyAddr PHY address
691  * @param[in] regAddr Register address
692  * @return Register value
693  **/
694 
695 uint16_t pic32mzEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
696 {
697  uint_t i;
698 
699  //Set PHY address and register address
700  EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
701  //Start a read operation
702  EMAC1MCMD = _EMAC1MCMD_READ_MASK;
703 
704  //Wait for busy bit to be set
705  for(i = 0; i < 16; i++)
706  __asm__ __volatile__ ("nop;");
707 
708  //Wait for the read to complete
709  while(EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK);
710 
711  //Clear command register
712  EMAC1MCMD = 0;
713  //Return PHY register contents
714  return EMAC1MRDD & _EMAC1MRDD_MRDD_MASK;
715 }
716 
717 
718 /**
719  * @brief CRC calculation
720  * @param[in] data Pointer to the data over which to calculate the CRC
721  * @param[in] length Number of bytes to process
722  * @return Resulting CRC value
723  **/
724 
725 uint32_t pic32mzEthCalcCrc(const void *data, size_t length)
726 {
727  uint_t i;
728  uint_t j;
729 
730  //Point to the data over which to calculate the CRC
731  const uint8_t *p = (uint8_t *) data;
732  //CRC preset value
733  uint32_t crc = 0xFFFFFFFF;
734 
735  //Loop through data
736  for(i = 0; i < length; i++)
737  {
738  //The message is processed bit by bit
739  for(j = 0; j < 8; j++)
740  {
741  //Update CRC value
742  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
743  crc = (crc << 1) ^ 0x04C11DB7;
744  else
745  crc = crc << 1;
746  }
747  }
748 
749  //Return CRC value
750  return crc;
751 }
MacAddr addr
MAC address.
Definition: ethernet.h:210
const NicDriver pic32mzEthDriver
PIC32MZ Ethernet MAC driver.
uint16_t pic32mzEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
TCP/IP stack core.
void pic32mzEthIrqHandler(void)
PIC32MZ Ethernet MAC interrupt service routine.
#define ETH_TX_CTRL_BYTE_COUNT
Debugging facilities.
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
#define PIC32MZ_ETH_RX_BUFFER_COUNT
Generic error code.
Definition: error.h:43
#define txBuffer
#define _EMAC1MCFG_CLKSEL_DIV50
PIC32MZ Ethernet MAC controller.
#define PIC32MZ_ETH_IRQ_PRIORITY
#define ETH_TX_CTRL_SOP
#define PIC32MZ_ETH_RX_BUFFER_SIZE
#define ETH_RX_CTRL_EOP
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define ETH_RX_CTRL_BYTE_COUNT
#define PIC32MZ_ETH_TX_BUFFER_COUNT
error_t pic32mzEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
RX buffer descriptor.
void pic32mzEthEnableIrq(NetInterface *interface)
Enable interrupts.
void pic32mzEthDisableIrq(NetInterface *interface)
Disable interrupts.
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_TX_CTRL_EOWN
error_t pic32mzEthInit(NetInterface *interface)
PIC32MZ Ethernet MAC initialization.
void pic32mzEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define PIC32MZ_ETH_TX_BUFFER_SIZE
NIC driver.
Definition: nic.h:161
TX buffer descriptor.
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_TX_CTRL_NPV
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
#define ETH_TX_CTRL_EOP
error_t pic32mzEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:1266
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_RX_CTRL_NPV
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
#define ETH_RX_STATUS2_OK
#define rxBuffer
uint32_t pic32mzEthCalcCrc(const void *data, size_t length)
CRC calculation.
error_t pic32mzEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
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
void pic32mzEthTick(NetInterface *interface)
PIC32MZ Ethernet MAC timer handler.
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
#define ETH_RX_CTRL_EOWN
void pic32mzEthInitGpio(NetInterface *interface)
unsigned int uint_t
Definition: compiler_port.h:43
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
uint8_t value[]
Definition: dtls_misc.h:141
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:95
void pic32mzEthInitBufferDesc(NetInterface *interface)
Initialize DMA descriptor lists.
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
#define osExitIsr(flag)
#define osEnterIsr()
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
error_t pic32mzEthReceivePacket(NetInterface *interface)
Receive a packet.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
MAC filter table entry.
Definition: ethernet.h:208
#define PIC32MZ_ETH_IRQ_SUB_PRIORITY
#define TRACE_DEBUG(...)
Definition: debug.h:98
#define ETH_RX_CTRL_SOP
void pic32mzEthEventHandler(NetInterface *interface)
PIC32MZ Ethernet MAC event handler.