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-2021 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.1.2
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
42static 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
58static Pic32mxTxBufferDesc *txCurBufferDesc;
59//Pointer to the current RX buffer descriptor
60static 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//PIC32 Ethernet Starter Kit, PIC32 Ethernet Starter Kit II or
226//chipKIT Pro MX7 evaluation board?
227#if defined(USE_PIC32_ETH_STARTER_KIT) || defined(USE_PIC32_ETH_STARTER_KIT_2) || \
228 defined(USE_CHIPKIT_PRO_MX7)
229
230/**
231 * @brief GPIO configuration
232 * @param[in] interface Underlying network interface
233 **/
234
235void pic32mxEthInitGpio(NetInterface *interface)
236{
237 //No analog pins are shared with the alternate RMII interface
238}
239
240#endif
241
242
243/**
244 * @brief Initialize DMA descriptor lists
245 * @param[in] interface Underlying network interface
246 **/
247
249{
250 uint_t i;
251
252 //Initialize TX descriptor list
253 for(i = 0; i < PIC32MX_ETH_TX_BUFFER_COUNT; i++)
254 {
255 //Point to the current descriptor
256 txCurBufferDesc = &txBufferDesc[i];
257
258 //Use linked list rather than linear list
259 txCurBufferDesc->control = ETH_TX_CTRL_NPV;
260 //Transmit buffer address
261 txCurBufferDesc->address = KVA_TO_PA(txBuffer[i]);
262 //Transmit status vector
263 txCurBufferDesc->status1 = 0;
264 txCurBufferDesc->status2 = 0;
265 //Next descriptor address
266 txCurBufferDesc->next = KVA_TO_PA(&txBufferDesc[i + 1]);
267 }
268
269 //The last descriptor is chained to the first entry
270 txCurBufferDesc->next = KVA_TO_PA(&txBufferDesc[0]);
271 //Point to the very first descriptor
272 txCurBufferDesc = &txBufferDesc[0];
273
274 //Initialize RX descriptor list
275 for(i = 0; i < PIC32MX_ETH_RX_BUFFER_COUNT; i++)
276 {
277 //Point to the current descriptor
278 rxCurBufferDesc = &rxBufferDesc[i];
279
280 //The descriptor is initially owned by the DMA
281 rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
282 //Receive buffer address
283 rxCurBufferDesc->address = KVA_TO_PA(rxBuffer[i]);
284 //Receive status vector
285 rxCurBufferDesc->status1 = 0;
286 rxCurBufferDesc->status2 = 0;
287 //Next descriptor address
288 rxCurBufferDesc->next = KVA_TO_PA(&rxBufferDesc[i + 1]);
289 }
290
291 //The last descriptor is chained to the first entry
292 rxCurBufferDesc->next = KVA_TO_PA(&rxBufferDesc[0]);
293 //Point to the very first descriptor
294 rxCurBufferDesc = &rxBufferDesc[0];
295
296 //Starting address of TX descriptor table
297 ETHTXST = KVA_TO_PA(&txBufferDesc[0]);
298 //Starting address of RX descriptor table
299 ETHRXST = KVA_TO_PA(&rxBufferDesc[0]);
300 //Set receive buffer size
302}
303
304
305/**
306 * @brief PIC32MX Ethernet MAC timer handler
307 *
308 * This routine is periodically called by the TCP/IP stack to handle periodic
309 * operations such as polling the link state
310 *
311 * @param[in] interface Underlying network interface
312 **/
313
315{
316 //Valid Ethernet PHY or switch driver?
317 if(interface->phyDriver != NULL)
318 {
319 //Handle periodic operations
320 interface->phyDriver->tick(interface);
321 }
322 else if(interface->switchDriver != NULL)
323 {
324 //Handle periodic operations
325 interface->switchDriver->tick(interface);
326 }
327 else
328 {
329 //Just for sanity
330 }
331}
332
333
334/**
335 * @brief Enable interrupts
336 * @param[in] interface Underlying network interface
337 **/
338
340{
341 //Enable Ethernet MAC interrupts
342 IEC1SET = _IEC1_ETHIE_MASK;
343
344 //Valid Ethernet PHY or switch driver?
345 if(interface->phyDriver != NULL)
346 {
347 //Enable Ethernet PHY interrupts
348 interface->phyDriver->enableIrq(interface);
349 }
350 else if(interface->switchDriver != NULL)
351 {
352 //Enable Ethernet switch interrupts
353 interface->switchDriver->enableIrq(interface);
354 }
355 else
356 {
357 //Just for sanity
358 }
359}
360
361
362/**
363 * @brief Disable interrupts
364 * @param[in] interface Underlying network interface
365 **/
366
368{
369 //Disable Ethernet MAC interrupts
370 IEC1CLR = _IEC1_ETHIE_MASK;
371
372 //Valid Ethernet PHY or switch driver?
373 if(interface->phyDriver != NULL)
374 {
375 //Disable Ethernet PHY interrupts
376 interface->phyDriver->disableIrq(interface);
377 }
378 else if(interface->switchDriver != NULL)
379 {
380 //Disable Ethernet switch interrupts
381 interface->switchDriver->disableIrq(interface);
382 }
383 else
384 {
385 //Just for sanity
386 }
387}
388
389
390/**
391 * @brief PIC32MX Ethernet MAC interrupt service routine
392 **/
393
395{
396 bool_t flag;
397 uint32_t status;
398
399 //Interrupt service routine prologue
400 osEnterIsr();
401
402 //This flag will be set if a higher priority task must be woken
403 flag = FALSE;
404
405 //Read interrupt status register
406 status = ETHIRQ;
407
408 //Packet transmitted?
409 if((status & _ETHIRQ_TXDONE_MASK) != 0)
410 {
411 //Clear TXDONE interrupt flag
412 ETHIRQCLR = _ETHIRQ_TXDONE_MASK;
413
414 //Check whether the TX buffer is available for writing
415 if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) == 0)
416 {
417 //Notify the TCP/IP stack that the transmitter is ready to send
418 flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
419 }
420 }
421
422 //Packet received?
423 if((status & _ETHIRQ_PKTPEND_MASK) != 0)
424 {
425 //Disable PKTPEND interrupt
426 ETHIENCLR = _ETHIEN_PKTPENDIE_MASK;
427
428 //Set event flag
429 nicDriverInterface->nicEvent = TRUE;
430 //Notify the TCP/IP stack of the event
431 flag |= osSetEventFromIsr(&netEvent);
432 }
433
434 //Clear ETHIF interrupt flag before exiting the service routine
435 IFS1CLR = _IFS1_ETHIF_MASK;
436
437 //Interrupt service routine epilogue
438 osExitIsr(flag);
439}
440
441
442/**
443 * @brief PIC32MX Ethernet MAC event handler
444 * @param[in] interface Underlying network interface
445 **/
446
448{
449 error_t error;
450
451 //Packet received?
452 if((ETHIRQ & _ETHIRQ_PKTPEND_MASK) != 0)
453 {
454 //Process all pending packets
455 do
456 {
457 //Read incoming packet
458 error = pic32mxEthReceivePacket(interface);
459
460 //No more data in the receive buffer?
461 } while(error != ERROR_BUFFER_EMPTY);
462 }
463
464 //Re-enable PKTPEND interrupt
465 ETHIENSET = _ETHIEN_PKTPENDIE_MASK;
466}
467
468
469/**
470 * @brief Send a packet
471 * @param[in] interface Underlying network interface
472 * @param[in] buffer Multi-part buffer containing the data to send
473 * @param[in] offset Offset to the first data byte
474 * @param[in] ancillary Additional options passed to the stack along with
475 * the packet
476 * @return Error code
477 **/
478
480 const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
481{
482 size_t length;
483 uint32_t value;
484
485 //Retrieve the length of the packet
486 length = netBufferGetLength(buffer) - offset;
487
488 //Check the frame length
490 {
491 //The transmitter can accept another packet
492 osSetEvent(&interface->nicTxEvent);
493 //Report an error
495 }
496
497 //Make sure the current buffer is available for writing
498 if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) != 0)
499 {
500 return ERROR_FAILURE;
501 }
502
503 //Copy user data to the transmit buffer
504 netBufferRead(PA_TO_KVA1(txCurBufferDesc->address), buffer, offset, length);
505
506 //Write the number of bytes to send
508 //Set SOP and EOP flags since the data fits in a single buffer
510 //Give the ownership of the descriptor to the DMA
511 txCurBufferDesc->control = value | ETH_TX_CTRL_EOWN;
512
513 //Set TXRTS bit to start the transmission
514 ETHCON1SET = _ETHCON1_TXRTS_MASK;
515
516 //Point to the next descriptor in the list
517 txCurBufferDesc = PA_TO_KVA1(txCurBufferDesc->next);
518
519 //Check whether the next buffer is available for writing
520 if((txCurBufferDesc->control & ETH_TX_CTRL_EOWN) == 0)
521 {
522 //The transmitter can accept another packet
523 osSetEvent(&interface->nicTxEvent);
524 }
525
526 //Data successfully written
527 return NO_ERROR;
528}
529
530
531/**
532 * @brief Receive a packet
533 * @param[in] interface Underlying network interface
534 * @return Error code
535 **/
536
538{
539 static uint8_t temp[PIC32MX_ETH_RX_BUFFER_SIZE];
540 error_t error;
541 size_t n;
542 NetRxAncillary ancillary;
543
544 //Current buffer available for reading?
545 if((rxCurBufferDesc->control & ETH_RX_CTRL_EOWN) == 0)
546 {
547 //SOP and EOP flags should be set
548 if((rxCurBufferDesc->control & ETH_RX_CTRL_SOP) != 0 &&
549 (rxCurBufferDesc->control & ETH_RX_CTRL_EOP) != 0)
550 {
551 //Make sure no error occurred
552 if((rxCurBufferDesc->status2 & ETH_RX_STATUS2_OK) != 0)
553 {
554 //Retrieve the length of the frame
555 n = (rxCurBufferDesc->control & ETH_RX_CTRL_BYTE_COUNT) >> 16;
556 //Limit the number of data to read
558
559 //Copy data from the receive buffer
560 osMemcpy(temp, PA_TO_KVA1(rxCurBufferDesc->address), n);
561
562 //Additional options can be passed to the stack along with the packet
563 ancillary = NET_DEFAULT_RX_ANCILLARY;
564
565 //Pass the packet to the upper layer
566 nicProcessPacket(interface, temp, n, &ancillary);
567
568 //Valid packet received
569 error = NO_ERROR;
570 }
571 else
572 {
573 //The received packet contains an error
574 error = ERROR_INVALID_PACKET;
575 }
576 }
577 else
578 {
579 //The packet is not valid
580 error = ERROR_INVALID_PACKET;
581 }
582
583 //Give the ownership of the descriptor back to the DMA
584 rxCurBufferDesc->control = ETH_RX_CTRL_NPV | ETH_RX_CTRL_EOWN;
585
586 //Point to the next descriptor in the list
587 rxCurBufferDesc = PA_TO_KVA1(rxCurBufferDesc->next);
588
589 //Once software processes a received packet, it should write the BUFCDEC
590 //bit in order to decrement the packet buffer count BUFCNT
591 ETHCON1SET = _ETHCON1_BUFCDEC_MASK;
592 }
593 else
594 {
595 //No more data in the receive buffer
596 error = ERROR_BUFFER_EMPTY;
597 }
598
599 //Return status code
600 return error;
601}
602
603
604/**
605 * @brief Configure MAC address filtering
606 * @param[in] interface Underlying network interface
607 * @return Error code
608 **/
609
611{
612 uint_t i;
613 uint_t k;
614 uint32_t crc;
615 uint32_t hashTable[2];
616 MacFilterEntry *entry;
617
618 //Debug message
619 TRACE_DEBUG("Updating MAC filter...\r\n");
620
621 //Clear hash table
622 hashTable[0] = 0;
623 hashTable[1] = 0;
624
625 //The MAC address filter contains the list of MAC addresses to accept
626 //when receiving an Ethernet frame
627 for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
628 {
629 //Point to the current entry
630 entry = &interface->macAddrFilter[i];
631
632 //Valid entry?
633 if(entry->refCount > 0)
634 {
635 //Compute CRC over the current MAC address
636 crc = pic32mxEthCalcCrc(&entry->addr, sizeof(MacAddr));
637 //Calculate the corresponding index in the table
638 k = (crc >> 23) & 0x3F;
639 //Update hash table contents
640 hashTable[k / 32] |= (1 << (k % 32));
641 }
642 }
643
644 //Write the hash table
645 ETHHT0 = hashTable[0];
646 ETHHT1 = hashTable[1];
647
648 //Debug message
649 TRACE_DEBUG(" ETHHT0 = %08" PRIX32 "\r\n", ETHHT0);
650 TRACE_DEBUG(" ETHHT1 = %08" PRIX32 "\r\n", ETHHT1);
651
652 //Successful processing
653 return NO_ERROR;
654}
655
656
657/**
658 * @brief Adjust MAC configuration parameters for proper operation
659 * @param[in] interface Underlying network interface
660 * @return Error code
661 **/
662
664{
665 //Check current operating speed
666 if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
667 {
668 //100BASE-TX operation mode
669 EMAC1SUPPSET = _EMAC1SUPP_SPEEDRMII_MASK;
670 }
671 else
672 {
673 //10BASE-T operation mode
674 EMAC1SUPPCLR = _EMAC1SUPP_SPEEDRMII_MASK;
675 }
676
677 //Half-duplex or full-duplex mode?
678 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
679 {
680 //Configure FULLDPLX bit to match the current duplex mode
681 EMAC1CFG2SET = _EMAC1CFG2_FULLDPLX_MASK;
682 //Configure the Back-to-Back Inter-Packet Gap register
683 EMAC1IPGT = 0x15;
684 }
685 else
686 {
687 //Configure FULLDPLX bit to match the current duplex mode
688 EMAC1CFG2CLR = _EMAC1CFG2_FULLDPLX_MASK;
689 //Configure the Back-to-Back Inter-Packet Gap register
690 EMAC1IPGT = 0x12;
691 }
692
693 //Successful processing
694 return NO_ERROR;
695}
696
697
698/**
699 * @brief Write PHY register
700 * @param[in] opcode Access type (2 bits)
701 * @param[in] phyAddr PHY address (5 bits)
702 * @param[in] regAddr Register address (5 bits)
703 * @param[in] data Register value
704 **/
705
706void pic32mxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
707 uint8_t regAddr, uint16_t data)
708{
709 //Valid opcode?
711 {
712 //Set PHY address and register address
713 EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
714 //Start a write operation
715 EMAC1MWTD = data & _EMAC1MWTD_MWTD_MASK;
716
717 //Wait for busy bit to be set
718 __asm__ __volatile__ ("nop;");
719 __asm__ __volatile__ ("nop;");
720 __asm__ __volatile__ ("nop;");
721
722 //Wait for the write to complete
723 while((EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK) != 0)
724 {
725 }
726 }
727 else
728 {
729 //The MAC peripheral only supports standard Clause 22 opcodes
730 }
731}
732
733
734/**
735 * @brief Read PHY register
736 * @param[in] opcode Access type (2 bits)
737 * @param[in] phyAddr PHY address (5 bits)
738 * @param[in] regAddr Register address (5 bits)
739 * @return Register value
740 **/
741
742uint16_t pic32mxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
743 uint8_t regAddr)
744{
745 uint16_t data;
746
747 //Valid opcode?
749 {
750 //Set PHY address and register address
751 EMAC1MADR = (phyAddr << _EMAC1MADR_PHYADDR_POSITION) | regAddr;
752 //Start a read operation
753 EMAC1MCMD = _EMAC1MCMD_READ_MASK;
754
755 //Wait for busy bit to be set
756 __asm__ __volatile__ ("nop;");
757 __asm__ __volatile__ ("nop;");
758 __asm__ __volatile__ ("nop;");
759
760 //Wait for the read to complete
761 while((EMAC1MIND & _EMAC1MIND_MIIMBUSY_MASK) != 0)
762 {
763 }
764
765 //Clear command register
766 EMAC1MCMD = 0;
767 //Get register value
768 data = EMAC1MRDD & _EMAC1MRDD_MRDD_MASK;
769 }
770 else
771 {
772 //The MAC peripheral only supports standard Clause 22 opcodes
773 data = 0;
774 }
775
776 //Return the value of the PHY register
777 return data;
778}
779
780
781/**
782 * @brief CRC calculation
783 * @param[in] data Pointer to the data over which to calculate the CRC
784 * @param[in] length Number of bytes to process
785 * @return Resulting CRC value
786 **/
787
788uint32_t pic32mxEthCalcCrc(const void *data, size_t length)
789{
790 uint_t i;
791 uint_t j;
792 uint32_t crc;
793 const uint8_t *p;
794
795 //Point to the data over which to calculate the CRC
796 p = (uint8_t *) data;
797 //CRC preset value
798 crc = 0xFFFFFFFF;
799
800 //Loop through data
801 for(i = 0; i < length; i++)
802 {
803 //The message is processed bit by bit
804 for(j = 0; j < 8; j++)
805 {
806 //Update CRC value
807 if((((crc >> 31) ^ (p[i] >> j)) & 0x01) != 0)
808 {
809 crc = (crc << 1) ^ 0x04C11DB7;
810 }
811 else
812 {
813 crc = crc << 1;
814 }
815 }
816 }
817
818 //Return CRC value
819 return crc;
820}
#define rxBuffer
#define txBuffer
unsigned int uint_t
Definition: compiler_port.h:45
int bool_t
Definition: compiler_port.h:49
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:172
uint8_t value[]
Definition: dtls_misc.h:150
error_t
Error codes.
Definition: error.h:43
@ ERROR_BUFFER_EMPTY
Definition: error.h:140
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PACKET
Definition: error.h:139
@ ERROR_INVALID_LENGTH
Definition: error.h:110
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:941
#define ETH_MTU
Definition: ethernet.h:112
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:128
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
__start_packed struct @116 MacAddr
MAC address.
uint16_t regAddr
uint8_t p
Definition: ndp.h:298
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netEvent
Definition: net_legacy.h:267
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:672
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:123
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:110
#define osMemcpy(dest, src, length)
Definition: os_port.h:134
#define MIN(a, b)
Definition: os_port.h:62
#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.
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
void pic32mxEthInitGpio(NetInterface *interface)
#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
volatile Pic32mzCryptoBufferDesc cipherBufferDesc __attribute__((coherent, aligned(8)))
uint8_t data[]
Definition: sftp_common.h:228
uint32_t length
Definition: sftp_common.h:214
MAC filter table entry.
Definition: ethernet.h:255
MacAddr addr
MAC address.
Definition: ethernet.h:256
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:257
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:281
RX buffer descriptor.
TX buffer descriptor.