nuc472_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file nuc472_eth_driver.c
3  * @brief Nuvoton NUC472 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 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 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "nuc472_442.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 DMA descriptors
53 #pragma data_alignment = 4
55 //Receive DMA descriptors
56 #pragma data_alignment = 4
58 
59 //Keil MDK-ARM or GCC compiler?
60 #else
61 
62 //Transmit buffer
64  __attribute__((aligned(4)));
65 //Receive buffer
67  __attribute__((aligned(4)));
68 //Transmit DMA descriptors
70  __attribute__((aligned(4)));
71 //Receive DMA descriptors
73  __attribute__((aligned(4)));
74 
75 #endif
76 
77 //Current transmit descriptor
78 static uint_t txIndex;
79 //Current receive descriptor
80 static uint_t rxIndex;
81 
82 
83 /**
84  * @brief NUC472 Ethernet MAC driver
85  **/
86 
88 {
90  ETH_MTU,
101  TRUE,
102  TRUE,
103  TRUE,
104  FALSE
105 };
106 
107 
108 /**
109  * @brief NUC472 Ethernet MAC initialization
110  * @param[in] interface Underlying network interface
111  * @return Error code
112  **/
113 
115 {
116  error_t error;
117 
118  //Debug message
119  TRACE_INFO("Initializing NUC472 Ethernet MAC...\r\n");
120 
121  //Save underlying network interface
122  nicDriverInterface = interface;
123 
124  //Enable EMAC clock
125  CLK_EnableModuleClock(EMAC_MODULE);
126  //Select MDC clock frequency
127  CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(100));
128 
129  //Perform a software reset
130  EMAC->CTL |= EMAC_CTL_RST_Msk;
131  //Wait for the reset to complete
132  while(EMAC->CTL & EMAC_CTL_RST_Msk)
133  {
134  }
135 
136  //GPIO configuration
137  nuc472EthInitGpio(interface);
138 
139  //PHY transceiver initialization
140  error = interface->phyDriver->init(interface);
141  //Failed to initialize PHY transceiver?
142  if(error)
143  return error;
144 
145  //Set the upper 32 bits of the MAC address
146  EMAC->CAM0M = interface->macAddr.b[3] |
147  (interface->macAddr.b[2] << 8) |
148  (interface->macAddr.b[1] << 16) |
149  (interface->macAddr.b[0] << 24);
150 
151  //Set the lower 16 bits of the MAC address
152  EMAC->CAM0L = (interface->macAddr.b[5] << 16) |
153  (interface->macAddr.b[4] << 24);
154 
155  //Enable the corresponding CAM entry
156  EMAC->CAMEN = EMAC_CAMEN_CAMxEN_Msk << 0;
157  //Accept broadcast and multicast packets
158  EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk | EMAC_CAMCTL_ABP_Msk;
159 
160  //Maximum frame length that can be accepted
161  EMAC->MRFL = NUC472_ETH_RX_BUFFER_SIZE;
162 
163  //Initialize DMA descriptor lists
164  nuc472EthInitDmaDesc(interface);
165 
166  //Enable the desired MAC interrupts
167  EMAC->INTEN = EMAC_INTEN_TXCPIEN_Msk | EMAC_INTEN_TXIEN_Msk |
168  EMAC_INTEN_RXGDIEN_Msk | EMAC_INTEN_RXIEN_Msk;
169 
170  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
171  NVIC_SetPriorityGrouping(NUC472_ETH_IRQ_PRIORITY_GROUPING);
172 
173  //Configure EMAC transmit interrupt priority
174  NVIC_SetPriority(EMAC_TX_IRQn, NVIC_EncodePriority(NUC472_ETH_IRQ_PRIORITY_GROUPING,
176 
177  //Configure EMAC receive interrupt priority
178  NVIC_SetPriority(EMAC_RX_IRQn, NVIC_EncodePriority(NUC472_ETH_IRQ_PRIORITY_GROUPING,
180 
181  //Enable transmission and reception
182  EMAC->CTL |= EMAC_CTL_TXON_Msk | EMAC_CTL_RXON_Msk;
183 
184  //Accept any packets from the upper layer
185  osSetEvent(&interface->nicTxEvent);
186 
187  //Successful initialization
188  return NO_ERROR;
189 }
190 
191 
192 //NuTiny-SDK-NUC472 or NuMaker-PFM-NUC472 evaluation board?
193 #if defined(USE_NUTINY_SDK_NUC472) || defined(USE_NUMAKER_PFM_NUC472)
194 
195 /**
196  * @brief GPIO configuration
197  * @param[in] interface Underlying network interface
198  **/
199 
200 void nuc472EthInitGpio(NetInterface *interface)
201 {
202  uint32_t temp;
203 
204  //Select RMII interface mode
205  EMAC->CTL |= EMAC_CTL_RMIIEN_Msk | EMAC_CTL_RMIIRXCTL_Msk;
206 
207  //Configure EMAC_MII_MDC (PB.14) and EMAC_MII_MDIO (PB.15)
208  temp = SYS->GPB_MFPH;
209  temp = (temp & ~SYS_GPB_MFPH_PB14MFP_Msk) | SYS_GPB_MFPH_PB14MFP_EMAC_MII_MDC;
210  temp = (temp & ~SYS_GPB_MFPH_PB15MFP_Msk) | SYS_GPB_MFPH_PB15MFP_EMAC_MII_MDIO;
211  SYS->GPB_MFPH = temp;
212 
213  //Configure EMAC_REFCLK (PC.0), EMAC_MII_RXERR (PC.1), EMAC_MII_RXDV (PC.2),
214  //EMAC_MII_RXD1 (PC.3), EMAC_MII_RXD0 (PC.4), EMAC_MII_TXD0 (PC.6) and
215  //EMAC_MII_TXD1 (PC.7)
216  temp = SYS->GPC_MFPL;
217  temp = (temp & ~SYS_GPC_MFPL_PC0MFP_Msk) | SYS_GPC_MFPL_PC0MFP_EMAC_REFCLK;
218  temp = (temp & ~SYS_GPC_MFPL_PC1MFP_Msk) | SYS_GPC_MFPL_PC1MFP_EMAC_MII_RXERR;
219  temp = (temp & ~SYS_GPC_MFPL_PC2MFP_Msk) | SYS_GPC_MFPL_PC2MFP_EMAC_MII_RXDV;
220  temp = (temp & ~SYS_GPC_MFPL_PC3MFP_Msk) | SYS_GPC_MFPL_PC3MFP_EMAC_MII_RXD1;
221  temp = (temp & ~SYS_GPC_MFPL_PC4MFP_Msk) | SYS_GPC_MFPL_PC4MFP_EMAC_MII_RXD0;
222  temp = (temp & ~SYS_GPC_MFPL_PC6MFP_Msk) | SYS_GPC_MFPL_PC6MFP_EMAC_MII_TXD0;
223  temp = (temp & ~SYS_GPC_MFPL_PC7MFP_Msk) | SYS_GPC_MFPL_PC7MFP_EMAC_MII_TXD1;
224  SYS->GPC_MFPL = temp;
225 
226  //Configure EMAC_MII_TXEN (PC.8)
227  temp = SYS->GPC_MFPH;
228  temp = (temp & ~SYS_GPC_MFPH_PC8MFP_Msk) | SYS_GPC_MFPH_PC8MFP_EMAC_MII_TXEN;
229  SYS->GPC_MFPH = temp;
230 
231  //Enable high slew rate on RMII output pins
232  PC->SLEWCTL |= GPIO_SLEWCTL_HSREN6_Msk | GPIO_SLEWCTL_HSREN7_Msk |
233  GPIO_SLEWCTL_HSREN8_Msk;
234 }
235 
236 #endif
237 
238 
239 /**
240  * @brief Initialize DMA descriptor lists
241  * @param[in] interface Underlying network interface
242  **/
243 
245 {
246  uint_t i;
247 
248  //Initialize TX DMA descriptor list
249  for(i = 0; i < NUC472_ETH_TX_BUFFER_COUNT; i++)
250  {
251  //The descriptor is initially owned by the CPU
252  txDmaDesc[i].txdes0 = 0;
253  //Transmit buffer address
254  txDmaDesc[i].txdes1 = (uint32_t) txBuffer[i];
255  //Transmit frame status
256  txDmaDesc[i].txdes2 = 0;
257  //Next descriptor address
258  txDmaDesc[i].txdes3 = (uint32_t) &txDmaDesc[i + 1];
259  }
260 
261  //The last descriptor is chained to the first entry
262  txDmaDesc[i - 1].txdes3 = (uint32_t) &txDmaDesc[0];
263  //Initialize TX descriptor index
264  txIndex = 0;
265 
266  //Initialize RX DMA descriptor list
267  for(i = 0; i < NUC472_ETH_RX_BUFFER_COUNT; i++)
268  {
269  //The descriptor is initially owned by the DMA
270  rxDmaDesc[i].rxdes0 = EMAC_RXDES0_OWNER;
271  //Receive buffer address
272  rxDmaDesc[i].rxdes1 = (uint32_t) rxBuffer[i];
273  //Reserved field
274  rxDmaDesc[i].rxdes2 = 0;
275  //Next descriptor address
276  rxDmaDesc[i].rxdes3 = (uint32_t) &rxDmaDesc[i + 1];
277  }
278 
279  //The last descriptor is chained to the first entry
280  rxDmaDesc[i - 1].rxdes3 = (uint32_t) &rxDmaDesc[0];
281  //Initialize RX descriptor index
282  rxIndex = 0;
283 
284  //Start address of the TX descriptor list
285  EMAC->TXDSA = (uint32_t) txDmaDesc;
286  //Start address of the RX descriptor list
287  EMAC->RXDSA = (uint32_t) rxDmaDesc;
288 }
289 
290 
291 /**
292  * @brief NUC472 Ethernet MAC timer handler
293  *
294  * This routine is periodically called by the TCP/IP stack to
295  * handle periodic operations such as polling the link state
296  *
297  * @param[in] interface Underlying network interface
298  **/
299 
300 void nuc472EthTick(NetInterface *interface)
301 {
302  //Handle periodic operations
303  interface->phyDriver->tick(interface);
304 }
305 
306 
307 /**
308  * @brief Enable interrupts
309  * @param[in] interface Underlying network interface
310  **/
311 
313 {
314  //Enable Ethernet MAC interrupts
315  NVIC_EnableIRQ(EMAC_TX_IRQn);
316  NVIC_EnableIRQ(EMAC_RX_IRQn);
317 
318  //Enable Ethernet PHY interrupts
319  interface->phyDriver->enableIrq(interface);
320 }
321 
322 
323 /**
324  * @brief Disable interrupts
325  * @param[in] interface Underlying network interface
326  **/
327 
329 {
330  //Disable Ethernet MAC interrupts
331  NVIC_DisableIRQ(EMAC_TX_IRQn);
332  NVIC_DisableIRQ(EMAC_RX_IRQn);
333 
334  //Disable Ethernet PHY interrupts
335  interface->phyDriver->disableIrq(interface);
336 }
337 
338 
339 /**
340  * @brief Ethernet MAC transmit interrupt
341  **/
342 
344 {
345  bool_t flag;
346 
347  //Interrupt service routine prologue
348  osEnterIsr();
349 
350  //This flag will be set if a higher priority task must be woken
351  flag = FALSE;
352 
353  //A packet has been transmitted?
354  if(EMAC->INTSTS & EMAC_INTSTS_TXCPIF_Msk)
355  {
356  //Clear TXCPIF interrupt flag
357  EMAC->INTSTS = EMAC_INTSTS_TXCPIF_Msk;
358 
359  //Check whether the TX buffer is available for writing
360  if(!(txDmaDesc[txIndex].txdes0 & EMAC_TXDES0_OWNER))
361  {
362  //Notify the TCP/IP stack that the transmitter is ready to send
363  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
364  }
365  }
366 
367  //Interrupt service routine epilogue
368  osExitIsr(flag);
369 }
370 
371 
372 /**
373  * @brief Ethernet MAC receive interrupt
374  **/
375 
377 {
378  bool_t flag;
379 
380  //Interrupt service routine prologue
381  osEnterIsr();
382 
383  //This flag will be set if a higher priority task must be woken
384  flag = FALSE;
385 
386  //A packet has been received?
387  if(EMAC->INTSTS & EMAC_INTSTS_RXGDIF_Msk)
388  {
389  //Disable receive interrupts
390  EMAC->INTEN &= ~EMAC_INTEN_RXIEN_Msk;
391 
392  //Set event flag
393  nicDriverInterface->nicEvent = TRUE;
394  //Notify the TCP/IP stack of the event
395  flag |= osSetEventFromIsr(&netEvent);
396  }
397 
398  //Interrupt service routine epilogue
399  osExitIsr(flag);
400 }
401 
402 
403 /**
404  * @brief NUC472 Ethernet MAC event handler
405  * @param[in] interface Underlying network interface
406  **/
407 
409 {
410  error_t error;
411 
412  //Packet received?
413  if(EMAC->INTSTS & EMAC_INTSTS_RXGDIF_Msk)
414  {
415  //Clear interrupt flag
416  EMAC->INTSTS = EMAC_INTSTS_RXGDIF_Msk;
417 
418  //Process all pending packets
419  do
420  {
421  //Read incoming packet
422  error = nuc472EthReceivePacket(interface);
423 
424  //No more data in the receive buffer?
425  } while(error != ERROR_BUFFER_EMPTY);
426  }
427 
428  //Re-enable DMA interrupts
429  EMAC->INTEN = EMAC_INTEN_TXCPIEN_Msk | EMAC_INTEN_TXIEN_Msk |
430  EMAC_INTEN_RXGDIEN_Msk | EMAC_INTEN_RXIEN_Msk;
431 }
432 
433 
434 /**
435  * @brief Send a packet
436  * @param[in] interface Underlying network interface
437  * @param[in] buffer Multi-part buffer containing the data to send
438  * @param[in] offset Offset to the first data byte
439  * @return Error code
440  **/
441 
443  const NetBuffer *buffer, size_t offset)
444 {
445  size_t length;
446  uint_t txNextIndex;
447 
448  //Retrieve the length of the packet
449  length = netBufferGetLength(buffer) - offset;
450 
451  //Check the frame length
453  {
454  //The transmitter can accept another packet
455  osSetEvent(&interface->nicTxEvent);
456  //Report an error
457  return ERROR_INVALID_LENGTH;
458  }
459 
460  //Make sure the current buffer is available for writing
461  if(txDmaDesc[txIndex].txdes0 & EMAC_TXDES0_OWNER)
462  return ERROR_FAILURE;
463 
464  //Copy user data to the transmit buffer
465  netBufferRead((uint8_t *) txBuffer[txIndex], buffer, offset, length);
466 
467  //Calculate the index of the next descriptor
468  txNextIndex = txIndex + 1;
469 
470  //Wrap around if necessary
471  if(txNextIndex >= NUC472_ETH_TX_BUFFER_COUNT)
472  txNextIndex = 0;
473 
474  //Set the start address of the buffer
475  txDmaDesc[txIndex].txdes1 = (uint32_t) txBuffer[txIndex];
476  //Write the number of bytes to send
477  txDmaDesc[txIndex].txdes2 = length & EMAC_TXDES2_TBC;
478  //Set the address of the next descriptor
479  txDmaDesc[txIndex].txdes3 = (uint32_t) &txDmaDesc[txNextIndex];
480 
481  //Give the ownership of the descriptor to the DMA
482  txDmaDesc[txIndex].txdes0 = EMAC_TXDES0_OWNER | EMAC_TXDES0_INTEN |
484 
485  //Instruct the DMA to poll the transmit descriptor list
486  EMAC->TXST = 0;
487 
488  //Point to the next register
489  txIndex = txNextIndex;
490 
491  //Check whether the next buffer is available for writing
492  if(!(txDmaDesc[txIndex].txdes0 & EMAC_TXDES0_OWNER))
493  {
494  //The transmitter can accept another packet
495  osSetEvent(&interface->nicTxEvent);
496  }
497 
498  //Data successfully written
499  return NO_ERROR;
500 }
501 
502 
503 /**
504  * @brief Receive a packet
505  * @param[in] interface Underlying network interface
506  * @return Error code
507  **/
508 
510 {
511  error_t error;
512  size_t n;
513  uint_t rxNextIndex;
514 
515  //The current buffer is available for reading?
516  if(!(rxDmaDesc[rxIndex].rxdes0 & EMAC_RXDES0_OWNER))
517  {
518  //Valid frame received?
519  if(rxDmaDesc[rxIndex].rxdes0 & EMAC_RXDES0_RXGDIF)
520  {
521  //Retrieve the length of the frame
522  n = rxDmaDesc[rxIndex].rxdes0 & EMAC_RXDES0_RBC;
523  //Limit the number of data to read
525 
526  //Pass the packet to the upper layer
527  nicProcessPacket(interface, rxBuffer[rxIndex], n);
528 
529  //Valid packet received
530  error = NO_ERROR;
531  }
532  else
533  {
534  //The packet is not valid
535  error = ERROR_INVALID_PACKET;
536  }
537 
538  //Calculate the index of the next descriptor
539  rxNextIndex = rxIndex + 1;
540 
541  //Wrap around if necessary
542  if(rxNextIndex >= NUC472_ETH_RX_BUFFER_COUNT)
543  rxNextIndex = 0;
544 
545  //Set the start address of the buffer
546  rxDmaDesc[rxIndex].rxdes1 = (uint32_t) rxBuffer[rxIndex];
547  //Set the address of the next descriptor
548  rxDmaDesc[rxIndex].rxdes3 = (uint32_t) &rxDmaDesc[rxNextIndex];
549  //Give the ownership of the descriptor back to the DMA
550  rxDmaDesc[rxIndex].rxdes0 = EMAC_RXDES0_OWNER;
551 
552  //Point to the next register
553  rxIndex = rxNextIndex;
554  }
555  else
556  {
557  //No more data in the receive buffer
558  error = ERROR_BUFFER_EMPTY;
559  }
560 
561  //Instruct the DMA to poll the receive descriptor list
562  EMAC->RXST = 0;
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  bool_t acceptMulticast;
579 
580  //Debug message
581  TRACE_DEBUG("Updating MAC filter...\r\n");
582 
583  //This flag will be set if multicast addresses should be accepted
584  acceptMulticast = FALSE;
585 
586  //The MAC address filter contains the list of MAC addresses to accept
587  //when receiving an Ethernet frame
588  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
589  {
590  //Valid entry?
591  if(interface->macAddrFilter[i].refCount > 0)
592  {
593  //Accept multicast addresses
594  acceptMulticast = TRUE;
595  //We are done
596  break;
597  }
598  }
599 
600  //Enable the reception of multicast frames if necessary
601  if(acceptMulticast)
602  EMAC->CAMCTL |= EMAC_CAMCTL_AMP_Msk;
603  else
604  EMAC->CAMCTL &= ~EMAC_CAMCTL_AMP_Msk;
605 
606  //Successful processing
607  return NO_ERROR;
608 }
609 
610 
611 /**
612  * @brief Adjust MAC configuration parameters for proper operation
613  * @param[in] interface Underlying network interface
614  * @return Error code
615  **/
616 
618 {
619  uint32_t config;
620 
621  //Read MAC control register
622  config = EMAC->CTL;
623 
624  //10BASE-T or 100BASE-TX operation mode?
625  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
626  config |= EMAC_CTL_OPMODE_Msk;
627  else
628  config &= ~EMAC_CTL_OPMODE_Msk;
629 
630  //Half-duplex or full-duplex mode?
631  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
632  config |= EMAC_CTL_FUDUP_Msk;
633  else
634  config &= ~EMAC_CTL_FUDUP_Msk;
635 
636  //Update MAC control register
637  EMAC->CTL = config;
638 
639  //Successful processing
640  return NO_ERROR;
641 }
642 
643 
644 /**
645  * @brief Write PHY register
646  * @param[in] opcode Access type (2 bits)
647  * @param[in] phyAddr PHY address (5 bits)
648  * @param[in] regAddr Register address (5 bits)
649  * @param[in] data Register value
650  **/
651 
652 void nuc472EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
653  uint8_t regAddr, uint16_t data)
654 {
655  uint32_t temp;
656 
657  //Valid opcode?
658  if(opcode == SMI_OPCODE_WRITE)
659  {
660  //Set up a write operation
661  temp = EMAC_MIIMCTL_MDCON_Msk | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk;
662  //PHY address
663  temp |= (phyAddr << EMAC_MIIMCTL_PHYADDR_Pos) & EMAC_MIIMCTL_PHYADDR_Msk;
664  //Register address
665  temp |= (regAddr << EMAC_MIIMCTL_PHYREG_Pos) & EMAC_MIIMCTL_PHYREG_Msk;
666 
667  //Data to be written in the PHY register
668  EMAC->MIIMDAT = data & EMAC_MIIMDAT_DATA_Msk;
669 
670  //Start a write operation
671  EMAC->MIIMCTL = temp;
672  //Wait for the write to complete
673  while(EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk)
674  {
675  }
676  }
677  else
678  {
679  //The MAC peripheral only supports standard Clause 22 opcodes
680  }
681 }
682 
683 
684 /**
685  * @brief Read PHY register
686  * @param[in] opcode Access type (2 bits)
687  * @param[in] phyAddr PHY address (5 bits)
688  * @param[in] regAddr Register address (5 bits)
689  * @return Register value
690  **/
691 
692 uint16_t nuc472EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
693  uint8_t regAddr)
694 {
695  uint16_t data;
696  uint32_t temp;
697 
698  //Valid opcode?
699  if(opcode == SMI_OPCODE_READ)
700  {
701  //Set up a read operation
702  temp = EMAC_MIIMCTL_MDCON_Msk | EMAC_MIIMCTL_BUSY_Msk;
703  //PHY address
704  temp |= (phyAddr << EMAC_MIIMCTL_PHYADDR_Pos) & EMAC_MIIMCTL_PHYADDR_Msk;
705  //Register address
706  temp |= (regAddr << EMAC_MIIMCTL_PHYREG_Pos) & EMAC_MIIMCTL_PHYREG_Msk;
707 
708  //Start a read operation
709  EMAC->MIIMCTL = temp;
710  //Wait for the read to complete
711  while(EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk)
712  {
713  }
714 
715  //Get register value
716  data = EMAC->MIIMDAT & EMAC_MIIMDAT_DATA_Msk;
717  }
718  else
719  {
720  //The MAC peripheral only supports standard Clause 22 opcodes
721  data = 0;
722  }
723 
724  //Return the value of the PHY register
725  return data;
726 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
const NicDriver nuc472EthDriver
NUC472 Ethernet MAC driver.
uint8_t length
Definition: dtls_misc.h:149
#define EMAC_RXDES0_RBC
TX DMA descriptor.
uint8_t opcode
Definition: dns_common.h:172
error_t nuc472EthInit(NetInterface *interface)
NUC472 Ethernet MAC initialization.
int bool_t
Definition: compiler_port.h:49
void nuc472EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define EMAC_TXDES0_INTEN
Nuvoton NUC472 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:672
#define EMAC_TXDES0_OWNER
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
void nuc472EthTick(NetInterface *interface)
NUC472 Ethernet MAC timer handler.
RX DMA descriptor.
#define NUC472_ETH_RX_BUFFER_SIZE
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:62
error_t nuc472EthReceivePacket(NetInterface *interface)
Receive a packet.
void nuc472EthDisableIrq(NetInterface *interface)
Disable interrupts.
error_t nuc472EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
error_t nuc472EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define NUC472_ETH_IRQ_GROUP_PRIORITY
#define FALSE
Definition: os_port.h:46
#define NUC472_ETH_TX_BUFFER_SIZE
error_t
Error codes.
Definition: error.h:42
void nuc472EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
Generic error code.
Definition: error.h:45
uint16_t nuc472EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define txBuffer
#define NetInterface
Definition: net.h:36
#define EMAC_RXDES0_RXGDIF
#define NUC472_ETH_TX_BUFFER_COUNT
void nuc472EthEventHandler(NetInterface *interface)
NUC472 Ethernet MAC event handler.
#define NUC472_ETH_IRQ_SUB_PRIORITY
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
error_t nuc472EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define TRACE_INFO(...)
Definition: debug.h:94
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:62
#define EMAC_TXDES2_TBC
#define rxBuffer
#define EMAC_TXDES0_CRCAPP
#define EMAC_RXDES0_OWNER
#define TRACE_DEBUG(...)
Definition: debug.h:106
uint16_t regAddr
void nuc472EthInitGpio(NetInterface *interface)
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
#define NUC472_ETH_RX_BUFFER_COUNT
#define osEnterIsr()
void EMAC_TX_IRQHandler(void)
Ethernet MAC transmit interrupt.
#define NUC472_ETH_IRQ_PRIORITY_GROUPING
#define rxDmaDesc
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define EMAC_TXDES0_PADEN
#define txDmaDesc
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
NIC driver.
Definition: nic.h:179
void EMAC_RX_IRQHandler(void)
Ethernet MAC receive interrupt.
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
Ethernet interface.
Definition: nic.h:79
void nuc472EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.