lpc175x_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file lpc175x_eth_driver.c
3  * @brief LPC1758 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 "lpc17xx.h"
36 #include "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *nicDriverInterface;
42 
43 //IAR EWARM compiler?
44 #if defined(__ICCARM__)
45 
46 //Transmit buffer
47 #pragma data_alignment = 4
49 //Receive buffer
50 #pragma data_alignment = 4
52 //Transmit descriptors
53 #pragma data_alignment = 4
55 //Transmit status array
56 #pragma data_alignment = 4
58 //Receive descriptors
59 #pragma data_alignment = 4
61 //Receive status array
62 #pragma data_alignment = 8
64 
65 //Keil MDK-ARM or GCC compiler?
66 #else
67 
68 //Transmit buffer
70  __attribute__((aligned(4)));
71 //Receive buffer
73  __attribute__((aligned(4)));
74 //Transmit descriptors
76  __attribute__((aligned(4)));
77 //Transmit status array
79  __attribute__((aligned(4)));
80 //Receive descriptors
82  __attribute__((aligned(4)));
83 //Receive status array
85  __attribute__((aligned(8)));
86 
87 #endif
88 
89 
90 /**
91  * @brief LPC175x Ethernet MAC driver
92  **/
93 
95 {
97  ETH_MTU,
108  TRUE,
109  TRUE,
110  TRUE,
111  FALSE
112 };
113 
114 
115 /**
116  * @brief LPC175x Ethernet MAC initialization
117  * @param[in] interface Underlying network interface
118  * @return Error code
119  **/
120 
122 {
123  error_t error;
124 
125  //Debug message
126  TRACE_INFO("Initializing LPC175x Ethernet MAC...\r\n");
127 
128  //Save underlying network interface
129  nicDriverInterface = interface;
130 
131  //Power up EMAC controller
132  LPC_SC->PCONP |= PCONP_PCENET;
133 
134  //GPIO configuration
135  lpc175xEthInitGpio(interface);
136 
137  //Reset host registers, transmit datapath and receive datapath
138  LPC_EMAC->Command = COMMAND_RX_RESET | COMMAND_TX_RESET | COMMAND_REG_RESET;
139 
140  //Reset EMAC controller
141  LPC_EMAC->MAC1 = MAC1_SOFT_RESET | MAC1_SIMULATION_RESET |
143 
144  //Initialize MAC related registers
145  LPC_EMAC->MAC1 = 0;
146  LPC_EMAC->MAC2 = MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE;
147  LPC_EMAC->IPGR = IPGR_DEFAULT_VALUE;
148  LPC_EMAC->CLRT = CLRT_DEFAULT_VALUE;
149 
150  //Select RMII mode
151  LPC_EMAC->Command = COMMAND_RMII;
152 
153  //Valid Ethernet PHY or switch driver?
154  if(interface->phyDriver != NULL)
155  {
156  //Ethernet PHY initialization
157  error = interface->phyDriver->init(interface);
158  }
159  else if(interface->switchDriver != NULL)
160  {
161  //Ethernet switch initialization
162  error = interface->switchDriver->init(interface);
163  }
164  else
165  {
166  //The interface is not properly configured
167  error = ERROR_FAILURE;
168  }
169 
170  //Any error to report?
171  if(error)
172  {
173  return error;
174  }
175 
176  //Initialize TX and RX descriptor arrays
177  lpc175xEthInitDesc(interface);
178 
179  //Set the MAC address of the station
180  LPC_EMAC->SA0 = interface->macAddr.w[2];
181  LPC_EMAC->SA1 = interface->macAddr.w[1];
182  LPC_EMAC->SA2 = interface->macAddr.w[0];
183 
184  //Initialize hash table
185  LPC_EMAC->HashFilterL = 0;
186  LPC_EMAC->HashFilterH = 0;
187 
188  //Configure the receive filter
189  LPC_EMAC->RxFilterCtrl = RFC_ACCEPT_PERFECT_EN |
191 
192  //Program the MAXF register with the maximum frame length to be accepted
193  LPC_EMAC->MAXF = LPC175X_ETH_RX_BUFFER_SIZE;
194 
195  //Reset EMAC interrupt flags
196  LPC_EMAC->IntClear = 0xFFFF;
197  //Enable desired EMAC interrupts
198  LPC_EMAC->IntEnable = INT_TX_DONE | INT_RX_DONE;
199 
200  //Set priority grouping (5 bits for pre-emption priority, no bits for subpriority)
201  NVIC_SetPriorityGrouping(LPC175X_ETH_IRQ_PRIORITY_GROUPING);
202 
203  //Configure Ethernet interrupt priority
204  NVIC_SetPriority(ENET_IRQn, NVIC_EncodePriority(LPC175X_ETH_IRQ_PRIORITY_GROUPING,
206 
207  //Enable transmission and reception
208  LPC_EMAC->Command |= COMMAND_TX_ENABLE | COMMAND_RX_ENABLE;
209  //Allow frames to be received
210  LPC_EMAC->MAC1 |= MAC1_RECEIVE_ENABLE;
211 
212  //Accept any packets from the upper layer
213  osSetEvent(&interface->nicTxEvent);
214 
215  //Successful initialization
216  return NO_ERROR;
217 }
218 
219 
220 /**
221  * @brief GPIO configuration
222  * @param[in] interface Underlying network interface
223  **/
224 
225 __weak_func void lpc175xEthInitGpio(NetInterface *interface)
226 {
227 //MCB1758 evaluation board?
228 #if defined(USE_MCB1758)
229  //Configure P1.0 (ENET_TXD0), P1.1 (ENET_TXD1), P1.4 (ENET_TX_EN), P1.8 (ENET_CRS),
230  //P1.9 (ENET_RXD0), P1.10 (ENET_RXD1), P1.14 (RX_ER) and P1.15 (ENET_REF_CLK)
231  LPC_PINCON->PINSEL2 &= ~(PINSEL2_P1_0_MASK | PINSEL2_P1_1_MASK |
232  PINSEL2_P1_4_MASK | PINSEL2_P1_8_MASK | PINSEL2_P1_9_MASK |
233  PINSEL2_P1_10_MASK | PINSEL2_P1_14_MASK | PINSEL2_P1_15_MASK);
234 
235  LPC_PINCON->PINSEL2 |= PINSEL2_P1_0_ENET_TXD0 | PINSEL2_P1_1_ENET_TXD1 |
236  PINSEL2_P1_4_ENET_TX_EN | PINSEL2_P1_8_ENET_CRS | PINSEL2_P1_9_ENET_RXD0 |
237  PINSEL2_P1_10_ENET_RXD1 | PINSEL2_P1_14_ENET_RX_ER | PINSEL2_P1_15_ENET_REF_CLK;
238 
239  //Configure P2.8 (ENET_MDC) and P2.9 (ENET_MDIO) as GPIOs
240  LPC_PINCON->PINSEL4 &= ~(PINSEL4_P2_8_MASK | PINSEL4_P2_9_MASK);
241  LPC_PINCON->PINSEL4 |= PINSEL4_P2_8_GPIO | PINSEL4_P2_9_GPIO;
242 
243  //SMI software implementation to drive MDC and MDIO
247 #endif
248 }
249 
250 
251 /**
252  * @brief Initialize TX and RX descriptors
253  * @param[in] interface Underlying network interface
254  **/
255 
257 {
258  uint_t i;
259 
260  //Initialize TX descriptors
261  for(i = 0; i < LPC175X_ETH_TX_BUFFER_COUNT; i++)
262  {
263  //Base address of the buffer containing transmit data
264  txDesc[i].packet = (uint32_t) txBuffer[i];
265  //Transmit descriptor control word
266  txDesc[i].control = 0;
267  //Transmit status information word
268  txStatus[i].info = 0;
269  }
270 
271  //Initialize RX descriptors
272  for(i = 0; i < LPC175X_ETH_RX_BUFFER_COUNT; i++)
273  {
274  //Base address of the buffer for storing receive data
275  rxDesc[i].packet = (uint32_t) rxBuffer[i];
276  //Receive descriptor control word
278  //Receive status information word
279  rxStatus[i].info = 0;
280  //Receive status HashCRC word
281  rxStatus[i].hashCrc = 0;
282  }
283 
284  //Initialize EMAC transmit descriptor registers
285  LPC_EMAC->TxDescriptor = (uint32_t) txDesc;
286  LPC_EMAC->TxStatus = (uint32_t) txStatus;
287  LPC_EMAC->TxDescriptorNumber = LPC175X_ETH_TX_BUFFER_COUNT - 1;
288  LPC_EMAC->TxProduceIndex = 0;
289 
290  //Initialize EMAC receive descriptor registers
291  LPC_EMAC->RxDescriptor = (uint32_t) rxDesc;
292  LPC_EMAC->RxStatus = (uint32_t) rxStatus;
293  LPC_EMAC->RxDescriptorNumber = LPC175X_ETH_RX_BUFFER_COUNT - 1;
294  LPC_EMAC->RxConsumeIndex = 0;
295 }
296 
297 
298 /**
299  * @brief LPC175x Ethernet MAC timer handler
300  *
301  * This routine is periodically called by the TCP/IP stack to handle periodic
302  * operations such as polling the link state
303  *
304  * @param[in] interface Underlying network interface
305  **/
306 
307 void lpc175xEthTick(NetInterface *interface)
308 {
309  //Valid Ethernet PHY or switch driver?
310  if(interface->phyDriver != NULL)
311  {
312  //Handle periodic operations
313  interface->phyDriver->tick(interface);
314  }
315  else if(interface->switchDriver != NULL)
316  {
317  //Handle periodic operations
318  interface->switchDriver->tick(interface);
319  }
320  else
321  {
322  //Just for sanity
323  }
324 }
325 
326 
327 /**
328  * @brief Enable interrupts
329  * @param[in] interface Underlying network interface
330  **/
331 
333 {
334  //Enable Ethernet MAC interrupts
335  NVIC_EnableIRQ(ENET_IRQn);
336 
337  //Valid Ethernet PHY or switch driver?
338  if(interface->phyDriver != NULL)
339  {
340  //Enable Ethernet PHY interrupts
341  interface->phyDriver->enableIrq(interface);
342  }
343  else if(interface->switchDriver != NULL)
344  {
345  //Enable Ethernet switch interrupts
346  interface->switchDriver->enableIrq(interface);
347  }
348  else
349  {
350  //Just for sanity
351  }
352 }
353 
354 
355 /**
356  * @brief Disable interrupts
357  * @param[in] interface Underlying network interface
358  **/
359 
361 {
362  //Disable Ethernet MAC interrupts
363  NVIC_DisableIRQ(ENET_IRQn);
364 
365  //Valid Ethernet PHY or switch driver?
366  if(interface->phyDriver != NULL)
367  {
368  //Disable Ethernet PHY interrupts
369  interface->phyDriver->disableIrq(interface);
370  }
371  else if(interface->switchDriver != NULL)
372  {
373  //Disable Ethernet switch interrupts
374  interface->switchDriver->disableIrq(interface);
375  }
376  else
377  {
378  //Just for sanity
379  }
380 }
381 
382 
383 /**
384  * @brief LPC175x Ethernet MAC interrupt service routine
385  **/
386 
387 void ENET_IRQHandler(void)
388 {
389  uint_t i;
390  bool_t flag;
391  uint32_t status;
392 
393  //Interrupt service routine prologue
394  osEnterIsr();
395 
396  //This flag will be set if a higher priority task must be woken
397  flag = FALSE;
398 
399  //Read interrupt status register
400  status = LPC_EMAC->IntStatus;
401 
402  //Packet transmitted?
403  if((status & INT_TX_DONE) != 0)
404  {
405  //Clear TxDone interrupt flag
406  LPC_EMAC->IntClear = INT_TX_DONE;
407 
408  //Get the index of the next descriptor
409  i = LPC_EMAC->TxProduceIndex + 1;
410 
411  //Wrap around if necessary
413  {
414  i = 0;
415  }
416 
417  //Check whether the TX buffer is available for writing
418  if(i != LPC_EMAC->TxConsumeIndex)
419  {
420  //Notify the TCP/IP stack that the transmitter is ready to send
421  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
422  }
423  }
424 
425  //Packet received?
426  if((status & INT_RX_DONE) != 0)
427  {
428  //Disable RxDone interrupts
429  LPC_EMAC->IntEnable &= ~INT_RX_DONE;
430 
431  //Set event flag
432  nicDriverInterface->nicEvent = TRUE;
433  //Notify the TCP/IP stack of the event
434  flag |= osSetEventFromIsr(&netEvent);
435  }
436 
437  //Interrupt service routine epilogue
438  osExitIsr(flag);
439 }
440 
441 
442 /**
443  * @brief LPC175x Ethernet MAC event handler
444  * @param[in] interface Underlying network interface
445  **/
446 
448 {
449  error_t error;
450 
451  //Packet received?
452  if((LPC_EMAC->IntStatus & INT_RX_DONE) != 0)
453  {
454  //Clear RxDone interrupt flag
455  LPC_EMAC->IntClear = INT_RX_DONE;
456 
457  //Process all pending packets
458  do
459  {
460  //Read incoming packet
461  error = lpc175xEthReceivePacket(interface);
462 
463  //No more data in the receive buffer?
464  } while(error != ERROR_BUFFER_EMPTY);
465  }
466 
467  //Re-enable TxDone and RxDone interrupts
468  LPC_EMAC->IntEnable = INT_TX_DONE | INT_RX_DONE;
469 }
470 
471 
472 /**
473  * @brief Send a packet
474  * @param[in] interface Underlying network interface
475  * @param[in] buffer Multi-part buffer containing the data to send
476  * @param[in] offset Offset to the first data byte
477  * @param[in] ancillary Additional options passed to the stack along with
478  * the packet
479  * @return Error code
480  **/
481 
483  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
484 {
485  uint_t i;
486  uint_t j;
487  size_t length;
488 
489  //Retrieve the length of the packet
490  length = netBufferGetLength(buffer) - offset;
491 
492  //Check the frame length
493  if(!length)
494  {
495  //The transmitter can accept another packet
496  osSetEvent(&interface->nicTxEvent);
497  //We are done since the buffer is empty
498  return NO_ERROR;
499  }
501  {
502  //The transmitter can accept another packet
503  osSetEvent(&interface->nicTxEvent);
504  //Report an error
505  return ERROR_INVALID_LENGTH;
506  }
507 
508  //Get the index of the current descriptor
509  i = LPC_EMAC->TxProduceIndex;
510  //Get the index of the next descriptor
511  j = i + 1;
512 
513  //Wrap around if necessary
515  {
516  j = 0;
517  }
518 
519  //Check whether the transmit descriptor array is full
520  if(j == LPC_EMAC->TxConsumeIndex)
521  {
522  return ERROR_FAILURE;
523  }
524 
525  //Copy user data to the transmit buffer
526  netBufferRead((uint8_t *) txDesc[i].packet, buffer, offset, length);
527 
528  //Write the transmit control word
529  txDesc[i].control = TX_CTRL_INTERRUPT | TX_CTRL_LAST |
531 
532  //Increment index and wrap around if necessary
533  if(++i >= LPC175X_ETH_TX_BUFFER_COUNT)
534  {
535  i = 0;
536  }
537 
538  //Save the resulting value
539  LPC_EMAC->TxProduceIndex = i;
540 
541  //Get the index of the next descriptor
542  j = i + 1;
543 
544  //Wrap around if necessary
546  {
547  j = 0;
548  }
549 
550  //Check whether the next buffer is available for writing
551  if(j != LPC_EMAC->TxConsumeIndex)
552  {
553  //The transmitter can accept another packet
554  osSetEvent(&interface->nicTxEvent);
555  }
556 
557  //Successful write operation
558  return NO_ERROR;
559 }
560 
561 
562 /**
563  * @brief Receive a packet
564  * @param[in] interface Underlying network interface
565  * @return Error code
566  **/
567 
569 {
570  error_t error;
571  size_t n;
572  uint_t i;
573  NetRxAncillary ancillary;
574 
575  //Point to the current descriptor
576  i = LPC_EMAC->RxConsumeIndex;
577 
578  //Current buffer available for reading?
579  if(i != LPC_EMAC->RxProduceIndex)
580  {
581  //Retrieve the length of the frame
582  n = (rxStatus[i].info & RX_STATUS_SIZE) + 1;
583  //Limit the number of data to read
585 
586  //Additional options can be passed to the stack along with the packet
587  ancillary = NET_DEFAULT_RX_ANCILLARY;
588 
589  //Pass the packet to the upper layer
590  nicProcessPacket(interface, (uint8_t *) rxDesc[i].packet, n, &ancillary);
591 
592  //Increment index and wrap around if necessary
593  if(++i >= LPC175X_ETH_RX_BUFFER_COUNT)
594  {
595  i = 0;
596  }
597 
598  //Save the resulting value
599  LPC_EMAC->RxConsumeIndex = i;
600 
601  //Valid packet received
602  error = NO_ERROR;
603  }
604  else
605  {
606  //No more data in the receive buffer
607  error = ERROR_BUFFER_EMPTY;
608  }
609 
610  //Return status code
611  return error;
612 }
613 
614 
615 /**
616  * @brief Configure MAC address filtering
617  * @param[in] interface Underlying network interface
618  * @return Error code
619  **/
620 
622 {
623  uint_t i;
624  uint_t k;
625  uint32_t crc;
626  uint32_t hashTable[2];
627  MacFilterEntry *entry;
628 
629  //Debug message
630  TRACE_DEBUG("Updating MAC filter...\r\n");
631 
632  //Set the MAC address of the station
633  LPC_EMAC->SA0 = interface->macAddr.w[2];
634  LPC_EMAC->SA1 = interface->macAddr.w[1];
635  LPC_EMAC->SA2 = interface->macAddr.w[0];
636 
637  //Clear hash table
638  hashTable[0] = 0;
639  hashTable[1] = 0;
640 
641  //The MAC address filter contains the list of MAC addresses to accept
642  //when receiving an Ethernet frame
643  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
644  {
645  //Point to the current entry
646  entry = &interface->macAddrFilter[i];
647 
648  //Valid entry?
649  if(entry->refCount > 0)
650  {
651  //Compute CRC over the current MAC address
652  crc = lpc175xEthCalcCrc(&entry->addr, sizeof(MacAddr));
653  //Bits [28:23] are used to form the hash
654  k = (crc >> 23) & 0x3F;
655  //Update hash table contents
656  hashTable[k / 32] |= (1 << (k % 32));
657  }
658  }
659 
660  //Write the hash table
661  LPC_EMAC->HashFilterL = hashTable[0];
662  LPC_EMAC->HashFilterH = hashTable[1];
663 
664  //Debug message
665  TRACE_DEBUG(" HashFilterL = %08" PRIX32 "\r\n", LPC_EMAC->HashFilterL);
666  TRACE_DEBUG(" HashFilterH = %08" PRIX32 "\r\n", LPC_EMAC->HashFilterH);
667 
668  //Successful processing
669  return NO_ERROR;
670 }
671 
672 
673 /**
674  * @brief Adjust MAC configuration parameters for proper operation
675  * @param[in] interface Underlying network interface
676  * @return Error code
677  **/
678 
680 {
681  //10BASE-T or 100BASE-TX operation mode?
682  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
683  {
684  LPC_EMAC->SUPP = SUPP_SPEED;
685  }
686  else
687  {
688  LPC_EMAC->SUPP = 0;
689  }
690 
691  //Half-duplex or full-duplex mode?
692  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
693  {
694  //The MAC operates in full-duplex mode
695  LPC_EMAC->MAC2 |= MAC2_FULL_DUPLEX;
696  LPC_EMAC->Command |= COMMAND_FULL_DUPLEX;
697  //Configure Back-to-Back Inter-Packet Gap
698  LPC_EMAC->IPGT = IPGT_FULL_DUPLEX;
699  }
700  else
701  {
702  //The MAC operates in half-duplex mode
703  LPC_EMAC->MAC2 &= ~MAC2_FULL_DUPLEX;
704  LPC_EMAC->Command &= ~COMMAND_FULL_DUPLEX;
705  //Configure Back-to-Back Inter-Packet Gap
706  LPC_EMAC->IPGT = IPGT_HALF_DUPLEX;
707  }
708 
709  //Successful processing
710  return NO_ERROR;
711 }
712 
713 
714 /**
715  * @brief Write PHY register
716  * @param[in] opcode Access type (2 bits)
717  * @param[in] phyAddr PHY address (5 bits)
718  * @param[in] regAddr Register address (5 bits)
719  * @param[in] data Register value
720  **/
721 
722 void lpc175xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
723  uint8_t regAddr, uint16_t data)
724 {
725  //Synchronization pattern
727  //Start of frame
729  //Set up a write operation
731  //Write PHY address
732  lpc175xEthWriteSmi(phyAddr, 5);
733  //Write register address
735  //Turnaround
737  //Write register value
739  //Release MDIO
741 }
742 
743 
744 /**
745  * @brief Read PHY register
746  * @param[in] opcode Access type (2 bits)
747  * @param[in] phyAddr PHY address (5 bits)
748  * @param[in] regAddr Register address (5 bits)
749  * @return Register value
750  **/
751 
752 uint16_t lpc175xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
753  uint8_t regAddr)
754 {
755  uint16_t data;
756 
757  //Synchronization pattern
759  //Start of frame
761  //Set up a read operation
763  //Write PHY address
764  lpc175xEthWriteSmi(phyAddr, 5);
765  //Write register address
767  //Turnaround to avoid contention
769  //Read register value
770  data = lpc175xEthReadSmi(16);
771  //Force the PHY to release the MDIO pin
773 
774  //Return PHY register contents
775  return data;
776 }
777 
778 
779 /**
780  * @brief SMI write operation
781  * @param[in] data Raw data to be written
782  * @param[in] length Number of bits to be written
783  **/
784 
786 {
787  //Skip the most significant bits since they are meaningless
788  data <<= 32 - length;
789 
790  //Configure MDIO as an output
792 
793  //Write the specified number of bits
794  while(length--)
795  {
796  //Write MDIO
797  if((data & 0x80000000) != 0)
798  {
800  }
801  else
802  {
804  }
805 
806  //Assert MDC
807  usleep(1);
809  //Deassert MDC
810  usleep(1);
812 
813  //Rotate data
814  data <<= 1;
815  }
816 }
817 
818 
819 /**
820  * @brief SMI read operation
821  * @param[in] length Number of bits to be read
822  * @return Data resulting from the MDIO read operation
823  **/
824 
826 {
827  uint32_t data = 0;
828 
829  //Configure MDIO as an input
831 
832  //Read the specified number of bits
833  while(length--)
834  {
835  //Rotate data
836  data <<= 1;
837 
838  //Assert MDC
840  usleep(1);
841  //Deassert MDC
843  usleep(1);
844 
845  //Check MDIO state
846  if((LPC175X_ETH_MDIO_GPIO->FIOPIN & LPC175X_ETH_MDIO_MASK) != 0)
847  {
848  data |= 0x01;
849  }
850  }
851 
852  //Return the received data
853  return data;
854 }
855 
856 
857 /**
858  * @brief CRC calculation
859  * @param[in] data Pointer to the data over which to calculate the CRC
860  * @param[in] length Number of bytes to process
861  * @return Resulting CRC value
862  **/
863 
864 uint32_t lpc175xEthCalcCrc(const void *data, size_t length)
865 {
866  uint_t i;
867  uint_t j;
868  uint32_t crc;
869  const uint8_t *p;
870 
871  //Point to the data over which to calculate the CRC
872  p = (uint8_t *) data;
873  //CRC preset value
874  crc = 0xFFFFFFFF;
875 
876  //Loop through data
877  for(i = 0; i < length; i++)
878  {
879  //The message is processed bit by bit
880  for(j = 0; j < 8; j++)
881  {
882  //Update CRC value
883  if((((crc >> 31) ^ (p[i] >> j)) & 0x01) != 0)
884  {
885  crc = (crc << 1) ^ 0x04C11DB7;
886  }
887  else
888  {
889  crc = crc << 1;
890  }
891  }
892  }
893 
894  //Return CRC value
895  return crc;
896 }
#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_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
MacAddr
Definition: ethernet.h:195
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
error_t lpc175xEthReceivePacket(NetInterface *interface)
Receive a packet.
error_t lpc175xEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
error_t lpc175xEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void lpc175xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
uint32_t lpc175xEthCalcCrc(const void *data, size_t length)
CRC calculation.
const NicDriver lpc175xEthDriver
LPC175x Ethernet MAC driver.
error_t lpc175xEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void ENET_IRQHandler(void)
LPC175x Ethernet MAC interrupt service routine.
void lpc175xEthEventHandler(NetInterface *interface)
LPC175x Ethernet MAC event handler.
void lpc175xEthDisableIrq(NetInterface *interface)
Disable interrupts.
uint16_t lpc175xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
__weak_func void lpc175xEthInitGpio(NetInterface *interface)
GPIO configuration.
void lpc175xEthInitDesc(NetInterface *interface)
Initialize TX and RX descriptors.
void lpc175xEthEnableIrq(NetInterface *interface)
Enable interrupts.
uint32_t lpc175xEthReadSmi(uint_t length)
SMI read operation.
void lpc175xEthWriteSmi(uint32_t data, uint_t length)
SMI write operation.
void lpc175xEthTick(NetInterface *interface)
LPC175x Ethernet MAC timer handler.
error_t lpc175xEthInit(NetInterface *interface)
LPC175x Ethernet MAC initialization.
LPC1758 Ethernet MAC driver.
#define LPC175X_ETH_IRQ_PRIORITY_GROUPING
#define MAC1_SOFT_RESET
#define COMMAND_TX_RESET
#define TX_CTRL_INTERRUPT
#define COMMAND_RX_ENABLE
#define COMMAND_RMII
#define SUPP_SPEED
#define MAC1_RESET_TX
#define LPC175X_ETH_MDC_MASK
#define COMMAND_FULL_DUPLEX
#define TX_CTRL_PAD
#define MAC2_FULL_DUPLEX
#define TX_CTRL_SIZE
#define MAC2_CRC_ENABLE
#define MAC1_RESET_MCS_TX
#define MAC2_PAD_CRC_ENABLE
#define LPC175X_ETH_TX_BUFFER_SIZE
#define LPC175X_ETH_IRQ_SUB_PRIORITY
#define COMMAND_REG_RESET
#define COMMAND_TX_ENABLE
#define LPC175X_ETH_MDIO_MASK
#define RFC_ACCEPT_BROADCAST_EN
#define IPGT_FULL_DUPLEX
#define MAC1_SIMULATION_RESET
#define INT_TX_DONE
#define LPC175X_ETH_MDC_GPIO
#define IPGT_HALF_DUPLEX
#define LPC175X_ETH_MDIO_GPIO
#define LPC175X_ETH_IRQ_GROUP_PRIORITY
#define LPC175X_ETH_RX_BUFFER_SIZE
#define RX_CTRL_INTERRUPT
#define LPC175X_ETH_TX_BUFFER_COUNT
#define MAC1_RESET_MCS_RX
#define COMMAND_RX_RESET
#define LPC175X_ETH_RX_BUFFER_COUNT
#define CLRT_DEFAULT_VALUE
#define MAC1_RESET_RX
#define MAC1_RECEIVE_ENABLE
#define IPGR_DEFAULT_VALUE
#define RFC_ACCEPT_PERFECT_EN
#define TX_CTRL_CRC
#define RX_STATUS_SIZE
#define INT_RX_DONE
#define RFC_ACCEPT_MULTICAST_HASH_EN
#define TX_CTRL_LAST
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_SYNC
Definition: nic.h:63
#define SMI_START
Definition: nic.h:64
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define SMI_TA
Definition: nic.h:68
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define usleep(delay)
Definition: os_port.h:297
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)
Receive descriptor.
Receive status.
Transmit descriptor.
Transmit status.
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
uint8_t length
Definition: tcp.h:368