lpc54608_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file lpc54608_eth_driver.c
3  * @brief LPC54608 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 "fsl_device_registers.h"
34 #include "fsl_power.h"
35 #include "fsl_reset.h"
36 #include "fsl_clock.h"
37 #include "fsl_iocon.h"
38 #include "fsl_gpio.h"
39 #include "core/net.h"
41 #include "debug.h"
42 
43 //Underlying network interface
44 static NetInterface *nicDriverInterface;
45 
46 //IAR EWARM compiler?
47 #if defined(__ICCARM__)
48 
49 //Transmit buffer
50 #pragma data_alignment = 4
52 //Receive buffer
53 #pragma data_alignment = 4
55 //Transmit DMA descriptors
56 #pragma data_alignment = 4
58 //Receive DMA descriptors
59 #pragma data_alignment = 4
61 
62 //Keil MDK-ARM or GCC compiler?
63 #else
64 
65 //Transmit buffer
67  __attribute__((aligned(4)));
68 //Receive buffer
70  __attribute__((aligned(4)));
71 //Transmit DMA descriptors
73  __attribute__((aligned(4)));
74 //Receive DMA descriptors
76  __attribute__((aligned(4)));
77 
78 #endif
79 
80 //Current transmit descriptor
81 static uint_t txIndex;
82 //Current receive descriptor
83 static uint_t rxIndex;
84 
85 
86 /**
87  * @brief LPC54608 Ethernet MAC driver
88  **/
89 
91 {
93  ETH_MTU,
104  TRUE,
105  TRUE,
106  TRUE,
107  FALSE
108 };
109 
110 
111 /**
112  * @brief LPC54608 Ethernet MAC initialization
113  * @param[in] interface Underlying network interface
114  * @return Error code
115  **/
116 
118 {
119  error_t error;
120 
121  //Debug message
122  TRACE_INFO("Initializing LPC54608 Ethernet MAC...\r\n");
123 
124  //Save underlying network interface
125  nicDriverInterface = interface;
126 
127  //Enable ENET peripheral clock
128  CLOCK_EnableClock(kCLOCK_Eth);
129  //Reset ENET module
130  RESET_PeripheralReset(kETH_RST_SHIFT_RSTn);
131 
132  //GPIO configuration
133  lpc54608EthInitGpio(interface);
134 
135  //Perform a software reset
136  ENET->DMA_MODE |= ENET_DMA_MODE_SWR_MASK;
137  //Wait for the reset to complete
138  while(ENET->DMA_MODE & ENET_DMA_MODE_SWR_MASK);
139 
140  //Adjust MDC clock range depending on CSR frequency
141  ENET->MAC_MDIO_ADDR = ENET_MAC_MDIO_ADDR_CR(4);
142 
143  //PHY transceiver initialization
144  error = interface->phyDriver->init(interface);
145  //Failed to initialize PHY transceiver?
146  if(error)
147  return error;
148 
149  //Use default MAC configuration
150  ENET->MAC_CONFIG = ENET_MAC_CONFIG_PS_MASK | ENET_MAC_CONFIG_DO_MASK;
151 
152  //Set the MAC address
153  ENET->MAC_ADDR_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
154  ENET->MAC_ADDR_HIGH = interface->macAddr.w[2];
155 
156  //Configure the receive filter
157  ENET->MAC_FRAME_FILTER = 0;
158 
159  //Disable flow control
160  ENET->MAC_TX_FLOW_CTRL_Q[0] = 0;
161  ENET->MAC_RX_FLOW_CTRL = 0;
162 
163  //Enable the first RX queue
164  ENET->MAC_RXQ_CTRL[0] = ENET_MAC_RXQ_CTRL_RXQ0EN(1);
165 
166  //Configure DMA operating mode
167  ENET->DMA_MODE = ENET_DMA_MODE_PR(0);
168  //Configure system bus mode
169  ENET->DMA_SYSBUS_MODE |= ENET_DMA_SYSBUS_MODE_AAL_MASK;
170 
171  //The DMA takes the descriptor table as contiguous
172  ENET->DMA_CH[0].DMA_CHX_CTRL = ENET_DMA_CH_DMA_CHX_CTRL_DSL(0);
173  //Configure TX features
174  ENET->DMA_CH[0].DMA_CHX_TX_CTRL = ENET_DMA_CH_DMA_CHX_TX_CTRL_TxPBL(1);
175 
176  //Configure RX features
177  ENET->DMA_CH[0].DMA_CHX_RX_CTRL = ENET_DMA_CH_DMA_CHX_RX_CTRL_RxPBL(1) |
178  ENET_DMA_CH_DMA_CHX_RX_CTRL_RBSZ(LPC54608_ETH_RX_BUFFER_SIZE / 4);
179 
180  //Enable store and forward mode for transmission
181  ENET->MTL_QUEUE[0].MTL_TXQX_OP_MODE |= ENET_MTL_QUEUE_MTL_TXQX_OP_MODE_TQS(7) |
182  ENET_MTL_QUEUE_MTL_TXQX_OP_MODE_TXQEN(2) |
183  ENET_MTL_QUEUE_MTL_TXQX_OP_MODE_TSF_MASK;
184 
185  //Enable store and forward mode for reception
186  ENET->MTL_QUEUE[0].MTL_RXQX_OP_MODE |= ENET_MTL_QUEUE_MTL_RXQX_OP_MODE_RQS(7) |
187  ENET_MTL_QUEUE_MTL_RXQX_OP_MODE_RSF_MASK;
188 
189  //Initialize DMA descriptor lists
190  lpc54608EthInitDmaDesc(interface);
191 
192  //Disable MAC interrupts
193  ENET->MAC_INTR_EN = 0;
194 
195  //Enable the desired DMA interrupts
196  ENET->DMA_CH[0].DMA_CHX_INT_EN = ENET_DMA_CH_DMA_CHX_INT_EN_NIE_MASK |
197  ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK;
198 
199  //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
200  NVIC_SetPriorityGrouping(LPC54608_ETH_IRQ_PRIORITY_GROUPING);
201 
202  //Configure Ethernet interrupt priority
203  NVIC_SetPriority(ETHERNET_IRQn, NVIC_EncodePriority(LPC54608_ETH_IRQ_PRIORITY_GROUPING,
205 
206  //Enable MAC transmission and reception
207  ENET->MAC_CONFIG |= ENET_MAC_CONFIG_TE_MASK | ENET_MAC_CONFIG_RE_MASK;
208 
209  //Enable DMA transmission and reception
210  ENET->DMA_CH[0].DMA_CHX_TX_CTRL |= ENET_DMA_CH_DMA_CHX_TX_CTRL_ST_MASK;
211  ENET->DMA_CH[0].DMA_CHX_RX_CTRL |= ENET_DMA_CH_DMA_CHX_RX_CTRL_SR_MASK;
212 
213  //Accept any packets from the upper layer
214  osSetEvent(&interface->nicTxEvent);
215 
216  //Successful initialization
217  return NO_ERROR;
218 }
219 
220 
221 //LPCXpresso54608 evaluation board?
222 #if defined(USE_LPCXPRESSO_54608)
223 
224 /**
225  * @brief GPIO configuration
226  * @param[in] interface Underlying network interface
227  **/
228 
229 void lpc54608EthInitGpio(NetInterface *interface)
230 {
231  gpio_pin_config_t pinConfig;
232 
233  //Select RMII interface mode
234  SYSCON->ETHPHYSEL |= SYSCON_ETHPHYSEL_PHY_SEL_MASK;
235 
236  //Enable IOCON clock
237  CLOCK_EnableClock(kCLOCK_Iocon);
238 
239  //Enable GPIO clocks
240  CLOCK_EnableClock(kCLOCK_Gpio0);
241  CLOCK_EnableClock(kCLOCK_Gpio4);
242 
243  //Configure ENET_TXD1 (PA0_17)
244  IOCON_PinMuxSet(IOCON, 0, 17, IOCON_FUNC7 | IOCON_MODE_INACT |
245  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
246 
247  //Configure ENET_TXD0 (PA4_8)
248  IOCON_PinMuxSet(IOCON, 4, 8, IOCON_FUNC1 | IOCON_MODE_INACT |
249  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
250 
251  //Configure ENET_RX_DV (PA4_10)
252  IOCON_PinMuxSet(IOCON, 4, 10, IOCON_FUNC1 | IOCON_MODE_INACT |
253  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
254 
255  //Configure ENET_RXD0 (PA4_11)
256  IOCON_PinMuxSet(IOCON, 4, 11, IOCON_FUNC1 | IOCON_MODE_INACT |
257  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
258 
259  //Configure ENET_RXD1 (PA4_12)
260  IOCON_PinMuxSet(IOCON, 4, 12, IOCON_FUNC1 | IOCON_MODE_INACT |
261  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
262 
263  //Configure ENET_TX_EN (PA4_13)
264  IOCON_PinMuxSet(IOCON, 4, 13, IOCON_FUNC1 | IOCON_MODE_INACT |
265  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
266 
267  //Configure ENET_RX_CLK (PA4_14)
268  IOCON_PinMuxSet(IOCON, 4, 14, IOCON_FUNC1 | IOCON_MODE_INACT |
269  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
270 
271  //Configure ENET_MDC (PA4_15)
272  IOCON_PinMuxSet(IOCON, 4, 15, IOCON_FUNC1 | IOCON_MODE_INACT |
273  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
274 
275  //Configure ENET_MDIO (PA4_16)
276  IOCON_PinMuxSet(IOCON, 4, 16, IOCON_FUNC1 | IOCON_MODE_PULLUP |
277  IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
278 
279  //Configure ENET_RST as an output
280  pinConfig.pinDirection = kGPIO_DigitalOutput;
281  pinConfig.outputLogic = 0;
282  GPIO_PinInit(GPIO, 2, 26, &pinConfig);
283 
284  //Reset PHY transceiver (hard reset)
285  GPIO_WritePinOutput(GPIO, 2, 26, 0);
286  sleep(10);
287  GPIO_WritePinOutput(GPIO, 2, 26, 1);
288  sleep(10);
289 }
290 
291 #endif
292 
293 
294 /**
295  * @brief Initialize DMA descriptor lists
296  * @param[in] interface Underlying network interface
297  **/
298 
300 {
301  uint_t i;
302 
303  //Initialize TX DMA descriptor list
304  for(i = 0; i < LPC54608_ETH_TX_BUFFER_COUNT; i++)
305  {
306  //The descriptor is initially owned by the application
307  txDmaDesc[i].tdes0 = 0;
308  txDmaDesc[i].tdes1 = 0;
309  txDmaDesc[i].tdes2 = 0;
310  txDmaDesc[i].tdes3 = 0;
311  }
312 
313  //Initialize TX descriptor index
314  txIndex = 0;
315 
316  //Initialize RX DMA descriptor list
317  for(i = 0; i < LPC54608_ETH_RX_BUFFER_COUNT; i++)
318  {
319  //The descriptor is initially owned by the DMA
320  rxDmaDesc[i].rdes0 = (uint32_t) rxBuffer[i];
321  rxDmaDesc[i].rdes1 = 0;
322  rxDmaDesc[i].rdes2 = 0;
324  }
325 
326  //Initialize RX descriptor index
327  rxIndex = 0;
328 
329  //Start location of the TX descriptor list
330  ENET->DMA_CH[0].DMA_CHX_TXDESC_LIST_ADDR = (uint32_t) &txDmaDesc[0];
331  //Length of the transmit descriptor ring
332  ENET->DMA_CH[0].DMA_CHX_TXDESC_RING_LENGTH = LPC54608_ETH_TX_BUFFER_COUNT - 1;
333 
334  //Start location of the RX descriptor list
335  ENET->DMA_CH[0].DMA_CHX_RXDESC_LIST_ADDR = (uint32_t) &rxDmaDesc[0];
336  //Length of the receive descriptor ring
337  ENET->DMA_CH[0].DMA_CHX_RXDESC_RING_LENGTH = LPC54608_ETH_RX_BUFFER_COUNT - 1;
338 }
339 
340 
341 /**
342  * @brief LPC54608 Ethernet MAC timer handler
343  *
344  * This routine is periodically called by the TCP/IP stack to
345  * handle periodic operations such as polling the link state
346  *
347  * @param[in] interface Underlying network interface
348  **/
349 
351 {
352  //Handle periodic operations
353  interface->phyDriver->tick(interface);
354 }
355 
356 
357 /**
358  * @brief Enable interrupts
359  * @param[in] interface Underlying network interface
360  **/
361 
363 {
364  //Enable Ethernet MAC interrupts
365  NVIC_EnableIRQ(ETHERNET_IRQn);
366  //Enable Ethernet PHY interrupts
367  interface->phyDriver->enableIrq(interface);
368 }
369 
370 
371 /**
372  * @brief Disable interrupts
373  * @param[in] interface Underlying network interface
374  **/
375 
377 {
378  //Disable Ethernet MAC interrupts
379  NVIC_DisableIRQ(ETHERNET_IRQn);
380  //Disable Ethernet PHY interrupts
381  interface->phyDriver->disableIrq(interface);
382 }
383 
384 
385 /**
386  * @brief LPC54608 Ethernet MAC interrupt service routine
387  **/
388 
390 {
391  bool_t flag;
392  uint32_t status;
393 
394  //Enter interrupt service routine
395  osEnterIsr();
396 
397  //This flag will be set if a higher priority task must be woken
398  flag = FALSE;
399 
400  //Read DMA status register
401  status = ENET->DMA_CH[0].DMA_CHX_STAT;
402 
403  //A packet has been transmitted?
404  if(status & ENET_DMA_CH_DMA_CHX_STAT_TI_MASK)
405  {
406  //Clear TI interrupt flag
407  ENET->DMA_CH[0].DMA_CHX_STAT = ENET_DMA_CH_DMA_CHX_STAT_TI_MASK;
408 
409  //Check whether the TX buffer is available for writing
410  if(!(txDmaDesc[txIndex].tdes3 & ENET_TDES3_OWN))
411  {
412  //Notify the TCP/IP stack that the transmitter is ready to send
413  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
414  }
415  }
416 
417  //A packet has been received?
418  if(status & ENET_DMA_CH_DMA_CHX_STAT_RI_MASK)
419  {
420  //Disable RIE interrupt
421  ENET->DMA_CH[0].DMA_CHX_INT_EN &= ~ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK;
422 
423  //Set event flag
424  nicDriverInterface->nicEvent = TRUE;
425  //Notify the TCP/IP stack of the event
426  flag |= osSetEventFromIsr(&netEvent);
427  }
428 
429  //Clear NIS interrupt flag
430  ENET->DMA_CH[0].DMA_CHX_STAT = ENET_DMA_CH_DMA_CHX_STAT_NIS_MASK;
431 
432  //Leave interrupt service routine
433  osExitIsr(flag);
434 }
435 
436 
437 /**
438  * @brief LPC54608 Ethernet MAC event handler
439  * @param[in] interface Underlying network interface
440  **/
441 
443 {
444  error_t error;
445 
446  //Packet received?
447  if(ENET->DMA_CH[0].DMA_CHX_STAT & ENET_DMA_CH_DMA_CHX_STAT_RI_MASK)
448  {
449  //Clear interrupt flag
450  ENET->DMA_CH[0].DMA_CHX_STAT = ENET_DMA_CH_DMA_CHX_STAT_RI_MASK;
451 
452  //Process all pending packets
453  do
454  {
455  //Read incoming packet
456  error = lpc54608EthReceivePacket(interface);
457 
458  //No more data in the receive buffer?
459  } while(error != ERROR_BUFFER_EMPTY);
460  }
461 
462  //Re-enable DMA interrupts
463  ENET->DMA_CH[0].DMA_CHX_INT_EN |= ENET_DMA_CH_DMA_CHX_INT_EN_NIE_MASK |
464  ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK;
465 }
466 
467 
468 /**
469  * @brief Send a packet
470  * @param[in] interface Underlying network interface
471  * @param[in] buffer Multi-part buffer containing the data to send
472  * @param[in] offset Offset to the first data byte
473  * @return Error code
474  **/
475 
477  const NetBuffer *buffer, size_t offset)
478 {
479  size_t length;
480 
481  //Retrieve the length of the packet
482  length = netBufferGetLength(buffer) - offset;
483 
484  //Check the frame length
486  {
487  //The transmitter can accept another packet
488  osSetEvent(&interface->nicTxEvent);
489  //Report an error
490  return ERROR_INVALID_LENGTH;
491  }
492 
493  //Make sure the current buffer is available for writing
494  if(txDmaDesc[txIndex].tdes3 & ENET_TDES3_OWN)
495  return ERROR_FAILURE;
496 
497  //Copy user data to the transmit buffer
498  netBufferRead(txBuffer[txIndex], buffer, offset, length);
499 
500  //Set the start address of the buffer
501  txDmaDesc[txIndex].tdes0 = (uint32_t) txBuffer[txIndex];
502  //Write the number of bytes to send
503  txDmaDesc[txIndex].tdes2 = ENET_TDES2_IOC | (length & ENET_TDES2_B1L);
504  //Give the ownership of the descriptor to the DMA
506 
507  //Clear TBU flag to resume processing
508  ENET->DMA_CH[0].DMA_CHX_STAT = ENET_DMA_CH_DMA_CHX_STAT_TBU_MASK;
509  //Instruct the DMA to poll the transmit descriptor list
510  ENET->DMA_CH[0].DMA_CHX_TXDESC_TAIL_PTR = 0;
511 
512  //Increment index and wrap around if necessary
513  if(++txIndex >= LPC54608_ETH_TX_BUFFER_COUNT)
514  txIndex = 0;
515 
516  //Check whether the next buffer is available for writing
517  if(!(txDmaDesc[txIndex].tdes3 & ENET_TDES3_OWN))
518  {
519  //The transmitter can accept another packet
520  osSetEvent(&interface->nicTxEvent);
521  }
522 
523  //Data successfully written
524  return NO_ERROR;
525 }
526 
527 
528 /**
529  * @brief Receive a packet
530  * @param[in] interface Underlying network interface
531  * @return Error code
532  **/
533 
535 {
536  error_t error;
537  size_t n;
538 
539  //The current buffer is available for reading?
540  if(!(rxDmaDesc[rxIndex].rdes3 & ENET_RDES3_OWN))
541  {
542  //FD and LD flags should be set
543  if((rxDmaDesc[rxIndex].rdes3 & ENET_RDES3_FD) &&
544  (rxDmaDesc[rxIndex].rdes3 & ENET_RDES3_LD))
545  {
546  //Make sure no error occurred
547  if(!(rxDmaDesc[rxIndex].rdes3 & ENET_RDES3_ES))
548  {
549  //Retrieve the length of the frame
550  n = rxDmaDesc[rxIndex].rdes3 & ENET_RDES3_PL;
551  //Limit the number of data to read
553 
554  //Pass the packet to the upper layer
555  nicProcessPacket(interface, rxBuffer[rxIndex], n);
556 
557  //Valid packet received
558  error = NO_ERROR;
559  }
560  else
561  {
562  //The received packet contains an error
563  error = ERROR_INVALID_PACKET;
564  }
565  }
566  else
567  {
568  //The packet is not valid
569  error = ERROR_INVALID_PACKET;
570  }
571 
572  //Set the start address of the buffer
573  rxDmaDesc[rxIndex].rdes0 = (uint32_t) rxBuffer[rxIndex];
574  //Give the ownership of the descriptor back to the DMA
576 
577  //Increment index and wrap around if necessary
578  if(++rxIndex >= LPC54608_ETH_RX_BUFFER_COUNT)
579  rxIndex = 0;
580  }
581  else
582  {
583  //No more data in the receive buffer
584  error = ERROR_BUFFER_EMPTY;
585  }
586 
587  //Clear RBU flag to resume processing
588  ENET->DMA_CH[0].DMA_CHX_STAT = ENET_DMA_CH_DMA_CHX_STAT_RBU_MASK;
589  //Instruct the DMA to poll the receive descriptor list
590  ENET->DMA_CH[0].DMA_CHX_RXDESC_TAIL_PTR = 0;
591 
592  //Return status code
593  return error;
594 }
595 
596 
597 /**
598  * @brief Configure MAC address filtering
599  * @param[in] interface Underlying network interface
600  * @return Error code
601  **/
602 
604 {
605  uint_t i;
606  bool_t acceptMulticast;
607 
608  //This flag will be set if multicast addresses should be accepted
609  acceptMulticast = FALSE;
610 
611  //The MAC address filter contains the list of MAC addresses to accept
612  //when receiving an Ethernet frame
613  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
614  {
615  //Valid entry?
616  if(interface->macAddrFilter[i].refCount > 0)
617  {
618  //Accept multicast addresses
619  acceptMulticast = TRUE;
620  //We are done
621  break;
622  }
623  }
624 
625  //Enable the reception of multicast frames if necessary
626  if(acceptMulticast)
627  ENET->MAC_FRAME_FILTER |= ENET_MAC_FRAME_FILTER_PM_MASK;
628  else
629  ENET->MAC_FRAME_FILTER &= ~ENET_MAC_FRAME_FILTER_PM_MASK;
630 
631  //Successful processing
632  return NO_ERROR;
633 }
634 
635 
636 /**
637  * @brief Adjust MAC configuration parameters for proper operation
638  * @param[in] interface Underlying network interface
639  * @return Error code
640  **/
641 
643 {
644  uint32_t config;
645 
646  //Read current MAC configuration
647  config = ENET->MAC_CONFIG;
648 
649  //10BASE-T or 100BASE-TX operation mode?
650  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
651  config |= ENET_MAC_CONFIG_FES_MASK;
652  else
653  config &= ~ENET_MAC_CONFIG_FES_MASK;
654 
655  //Half-duplex or full-duplex mode?
656  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
657  config |= ENET_MAC_CONFIG_DM_MASK;
658  else
659  config &= ~ENET_MAC_CONFIG_DM_MASK;
660 
661  //Update MAC configuration register
662  ENET->MAC_CONFIG = config;
663 
664  //Successful processing
665  return NO_ERROR;
666 }
667 
668 
669 /**
670  * @brief Write PHY register
671  * @param[in] phyAddr PHY address
672  * @param[in] regAddr Register address
673  * @param[in] data Register value
674  **/
675 
676 void lpc54608EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
677 {
678  uint32_t value;
679 
680  //Take care not to alter MDC clock configuration
681  value = ENET->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_CR_MASK;
682  //Set up a write operation
683  value |= ENET_MAC_MDIO_ADDR_MOC(1) | ENET_MAC_MDIO_ADDR_MB_MASK;
684  //PHY address
685  value |= ENET_MAC_MDIO_ADDR_PA(phyAddr);
686  //Register address
687  value |= ENET_MAC_MDIO_ADDR_RDA(regAddr);
688 
689  //Data to be written in the PHY register
690  ENET->MAC_MDIO_DATA = data & ENET_MAC_MDIO_DATA_MD_MASK;
691 
692  //Start a write operation
693  ENET->MAC_MDIO_ADDR = value;
694  //Wait for the write to complete
695  while(ENET->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_MB_MASK);
696 }
697 
698 
699 /**
700  * @brief Read PHY register
701  * @param[in] phyAddr PHY address
702  * @param[in] regAddr Register address
703  * @return Register value
704  **/
705 
706 uint16_t lpc54608EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
707 {
708  uint32_t value;
709 
710  //Take care not to alter MDC clock configuration
711  value = ENET->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_CR_MASK;
712  //Set up a read operation
713  value |= ENET_MAC_MDIO_ADDR_MOC(3) | ENET_MAC_MDIO_ADDR_MB_MASK;
714  //PHY address
715  value |= ENET_MAC_MDIO_ADDR_PA(phyAddr);
716  //Register address
717  value |= ENET_MAC_MDIO_ADDR_RDA(regAddr);
718 
719  //Start a read operation
720  ENET->MAC_MDIO_ADDR = value;
721  //Wait for the read to complete
722  while(ENET->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_MB_MASK);
723 
724  //Return PHY register contents
725  return ENET->MAC_MDIO_DATA & ENET_MAC_MDIO_DATA_MD_MASK;
726 }
error_t lpc54608EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define txDmaDesc
#define ENET_RDES3_FD
#define LPC54608_ETH_IRQ_GROUP_PRIORITY
#define LPC54608_ETH_IRQ_PRIORITY_GROUPING
TCP/IP stack core.
Debugging facilities.
#define LPC54608_ETH_TX_BUFFER_COUNT
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
#define ENET_RDES3_IOC
#define rxDmaDesc
#define txBuffer
void lpc54608EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t lpc54608EthReceivePacket(NetInterface *interface)
Receive a packet.
#define ENET_TDES3_FD
#define ENET_TDES2_B1L
#define sleep(delay)
Definition: os_port.h:126
Transmit descriptor.
#define LPC54608_ETH_RX_BUFFER_SIZE
uint16_t lpc54608EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
const NicDriver lpc54608EthDriver
LPC54608 Ethernet MAC driver.
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
void lpc54608EthTick(NetInterface *interface)
LPC54608 Ethernet MAC timer handler.
void lpc54608EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define ENET_TDES3_LD
Receive descriptor.
#define LPC54608_ETH_TX_BUFFER_SIZE
#define LPC54608_ETH_RX_BUFFER_COUNT
error_t lpc54608EthInit(NetInterface *interface)
LPC54608 Ethernet MAC initialization.
LPC54608 Ethernet MAC controller.
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
error_t lpc54608EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void ETHERNET_IRQHandler(void)
LPC54608 Ethernet MAC interrupt service routine.
NIC driver.
Definition: nic.h:161
#define ENET_RDES3_ES
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 ENET_RDES3_OWN
void lpc54608EthEventHandler(NetInterface *interface)
LPC54608 Ethernet MAC event handler.
#define ENET_TDES2_IOC
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
void lpc54608EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define rxBuffer
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 osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
unsigned int uint_t
Definition: compiler_port.h:43
void lpc54608EthInitGpio(NetInterface *interface)
uint8_t data[]
Definition: dtls_misc.h:167
error_t lpc54608EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define NetInterface
Definition: net.h:34
uint8_t value[]
Definition: dtls_misc.h:141
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
#define osExitIsr(flag)
#define osEnterIsr()
#define ENET_RDES3_PL
#define ENET_RDES3_LD
void lpc54608EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define LPC54608_ETH_IRQ_SUB_PRIORITY
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
#define ENET_RDES3_BUF1V
#define ENET_TDES3_OWN