rx63n_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file rx63n_eth_driver.c
3  * @brief Renesas RX63N Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2020 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.8
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <iorx63n.h>
36 #include <intrinsics.h>
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //IAR EWRX compiler?
45 #if defined(__ICCRX__)
46 
47 //Transmit buffer
48 #pragma data_alignment = 32
50 //Receive buffer
51 #pragma data_alignment = 32
53 //Transmit DMA descriptors
54 #pragma data_alignment = 32
56 //Receive DMA descriptors
57 #pragma data_alignment = 32
59 
60 //GCC compiler?
61 #else
62 
63 //Transmit buffer
65  __attribute__((aligned(32)));
66 //Receive buffer
68  __attribute__((aligned(32)));
69 //Transmit DMA descriptors
71  __attribute__((aligned(32)));
72 //Receive DMA descriptors
74  __attribute__((aligned(32)));
75 
76 #endif
77 
78 //Current transmit descriptor
79 static uint_t txIndex;
80 //Current receive descriptor
81 static uint_t rxIndex;
82 
83 
84 /**
85  * @brief RX63N Ethernet MAC driver
86  **/
87 
89 {
91  ETH_MTU,
102  TRUE,
103  TRUE,
104  TRUE,
105  TRUE
106 };
107 
108 
109 /**
110  * @brief RX63N Ethernet MAC initialization
111  * @param[in] interface Underlying network interface
112  * @return Error code
113  **/
114 
116 {
117  error_t error;
118 
119  //Debug message
120  TRACE_INFO("Initializing RX63N Ethernet MAC...\r\n");
121 
122  //Save underlying network interface
123  nicDriverInterface = interface;
124 
125  //Disable protection
126  SYSTEM.PRCR.WORD = 0xA50B;
127  //Cancel EDMAC module stop state
128  MSTP(EDMAC) = 0;
129  //Enable protection
130  SYSTEM.PRCR.WORD = 0xA500;
131 
132  //GPIO configuration
133  rx63nEthInitGpio(interface);
134 
135  //Reset EDMAC module
136  EDMAC.EDMR.BIT.SWR = 1;
137  sleep(10);
138 
139  //Valid Ethernet PHY or switch driver?
140  if(interface->phyDriver != NULL)
141  {
142  //Ethernet PHY initialization
143  error = interface->phyDriver->init(interface);
144  }
145  else if(interface->switchDriver != NULL)
146  {
147  //Ethernet switch initialization
148  error = interface->switchDriver->init(interface);
149  }
150  else
151  {
152  //The interface is not properly configured
153  error = ERROR_FAILURE;
154  }
155 
156  //Any error to report?
157  if(error)
158  {
159  return error;
160  }
161 
162  //Initialize DMA descriptor lists
163  rx63nEthInitDmaDesc(interface);
164 
165  //Maximum frame length that can be accepted
166  ETHERC.RFLR.LONG = RX63N_ETH_RX_BUFFER_SIZE;
167  //Set default inter packet gap (96-bit time)
168  ETHERC.IPGR.LONG = 0x14;
169 
170  //Set the upper 32 bits of the MAC address
171  ETHERC.MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
172  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
173 
174  //Set the lower 16 bits of the MAC address
175  ETHERC.MALR.BIT.MA = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
176 
177  //Set descriptor length (16 bytes)
178  EDMAC.EDMR.BIT.DL = 0;
179 
180 #ifdef _CPU_BIG_ENDIAN
181  //Select big endian mode
182  EDMAC.EDMR.BIT.DE = 0;
183 #else
184  //Select little endian mode
185  EDMAC.EDMR.BIT.DE = 1;
186 #endif
187 
188  //Use store and forward mode
189  EDMAC.TFTR.BIT.TFT = 0;
190 
191  //Set transmit FIFO size (2048 bytes)
192  EDMAC.FDR.BIT.TFD = 7;
193  //Set receive FIFO size (2048 bytes)
194  EDMAC.FDR.BIT.RFD = 7;
195 
196  //Enable continuous reception of multiple frames
197  EDMAC.RMCR.BIT.RNR = 1;
198 
199  //Accept transmit interrupt notifications
200  EDMAC.TRIMD.BIT.TIM = 0;
201  EDMAC.TRIMD.BIT.TIS = 1;
202 
203  //Disable all EDMAC interrupts
204  EDMAC.EESIPR.LONG = 0;
205  //Enable only the desired EDMAC interrupts
206  EDMAC.EESIPR.BIT.TWBIP = 1;
207  EDMAC.EESIPR.BIT.FRIP = 1;
208 
209  //Configure EDMAC interrupt priority
210  IPR(ETHER, EINT) = RX63N_ETH_IRQ_PRIORITY;
211 
212  //Enable transmission and reception
213  ETHERC.ECMR.BIT.TE = 1;
214  ETHERC.ECMR.BIT.RE = 1;
215 
216  //Instruct the DMA to poll the receive descriptor list
217  EDMAC.EDRRR.BIT.RR = 1;
218 
219  //Accept any packets from the upper layer
220  osSetEvent(&interface->nicTxEvent);
221 
222  //Successful initialization
223  return NO_ERROR;
224 }
225 
226 
227 //RDK RX63N or RSK RX63N evaluation board?
228 #if defined(USE_RDK_RX63N) || defined(USE_RSK_RX63N)
229 
230 /**
231  * @brief GPIO configuration
232  * @param[in] interface Underlying network interface
233  **/
234 
235 void rx63nEthInitGpio(NetInterface *interface)
236 {
237  //Unlock MPC registers
238  MPC.PWPR.BIT.B0WI = 0;
239  MPC.PWPR.BIT.PFSWE = 1;
240 
241 #if defined(USE_RDK_RX63N)
242  //Select RMII interface mode
243  MPC.PFENET.BIT.PHYMODE = 0;
244 
245  //Configure ET_MDIO (PA3)
246  PORTA.PMR.BIT.B3 = 1;
247  MPC.PA3PFS.BYTE = 0x11;
248 
249  //Configure ET_MDC (PA4)
250  PORTA.PMR.BIT.B4 = 1;
251  MPC.PA4PFS.BYTE = 0x11;
252 
253  //Configure ET_LINKSTA (PA5)
254  PORTA.PMR.BIT.B5 = 1;
255  MPC.PA5PFS.BYTE = 0x11;
256 
257  //Configure RMII_RXD1 (PB0)
258  PORTB.PMR.BIT.B0 = 1;
259  MPC.PB0PFS.BYTE = 0x12;
260 
261  //Configure RMII_RXD0 (PB1)
262  PORTB.PMR.BIT.B1 = 1;
263  MPC.PB1PFS.BYTE = 0x12;
264 
265  //Configure REF50CK (PB2)
266  PORTB.PMR.BIT.B2 = 1;
267  MPC.PB2PFS.BYTE = 0x12;
268 
269  //Configure RMII_RX_ER (PB3)
270  PORTB.PMR.BIT.B3 = 1;
271  MPC.PB3PFS.BYTE = 0x12;
272 
273  //Configure RMII_TXD_EN (PB4)
274  PORTB.PMR.BIT.B4 = 1;
275  MPC.PB4PFS.BYTE = 0x12;
276 
277  //Configure RMII_TXD0 (PB5)
278  PORTB.PMR.BIT.B5 = 1;
279  MPC.PB5PFS.BYTE = 0x12;
280 
281  //Configure RMII_TXD1 (PB6)
282  PORTB.PMR.BIT.B6 = 1;
283  MPC.PB6PFS.BYTE = 0x12;
284 
285  //Configure RMII_CRS_DV (PB7)
286  PORTB.PMR.BIT.B7 = 1;
287  MPC.PB7PFS.BYTE = 0x12;
288 
289 #elif defined(USE_RSK_RX63N)
290  //Select MII interface mode
291  MPC.PFENET.BIT.PHYMODE = 1;
292 
293  //Configure ET_MDIO (P71)
294  PORT7.PMR.BIT.B1 = 1;
295  MPC.P71PFS.BYTE = 0x11;
296 
297  //Configure ET_MDC (P72)
298  PORT7.PMR.BIT.B2 = 1;
299  MPC.P72PFS.BYTE = 0x11;
300 
301  //Configure ET_ERXD1 (P74)
302  PORT7.PMR.BIT.B4 = 1;
303  MPC.P74PFS.BYTE = 0x11;
304 
305  //Configure ET_ERXD0 P75)
306  PORT7.PMR.BIT.B5 = 1;
307  MPC.P75PFS.BYTE = 0x11;
308 
309  //Configure ET_RX_CLK (P76)
310  PORT7.PMR.BIT.B6 = 1;
311  MPC.P76PFS.BYTE = 0x11;
312 
313  //Configure ET_RX_ER (P77)
314  PORT7.PMR.BIT.B7 = 1;
315  MPC.P77PFS.BYTE = 0x11;
316 
317  //Configure ET_TX_EN (P80)
318  PORT8.PMR.BIT.B0 = 1;
319  MPC.P80PFS.BYTE = 0x11;
320 
321  //Configure ET_ETXD0 (P81)
322  PORT8.PMR.BIT.B1 = 1;
323  MPC.P81PFS.BYTE = 0x11;
324 
325  //Configure ET_ETXD1 (P82)
326  PORT8.PMR.BIT.B2 = 1;
327  MPC.P82PFS.BYTE = 0x11;
328 
329  //Configure ET_CRS (P83)
330  PORT8.PMR.BIT.B3 = 1;
331  MPC.P83PFS.BYTE = 0x11;
332 
333  //Configure ET_ERXD3 (PC0)
334  PORTC.PMR.BIT.B0 = 1;
335  MPC.PC0PFS.BYTE = 0x11;
336 
337  //Configure ET_ERXD2 (PC1)
338  PORTC.PMR.BIT.B1 = 1;
339  MPC.PC1PFS.BYTE = 0x11;
340 
341  //Configure ET_RX_DV (PC2)
342  PORTC.PMR.BIT.B2 = 1;
343  MPC.PC2PFS.BYTE = 0x11;
344 
345  //Configure ET_TX_ER (PC3)
346  PORTC.PMR.BIT.B3 = 1;
347  MPC.PC3PFS.BYTE = 0x11;
348 
349  //Configure ET_TX_CLK (PC4)
350  PORTC.PMR.BIT.B4 = 1;
351  MPC.PC4PFS.BYTE = 0x11;
352 
353  //Configure ET_ETXD2 (PC5)
354  PORTC.PMR.BIT.B5 = 1;
355  MPC.PC5PFS.BYTE = 0x11;
356 
357  //Configure ET_ETXD3 (PC6)
358  PORTC.PMR.BIT.B6 = 1;
359  MPC.PC6PFS.BYTE = 0x11;
360 
361  //Configure ET_COL (PC7)
362  PORTC.PMR.BIT.B7 = 1;
363  MPC.PC7PFS.BYTE = 0x11;
364 #endif
365 
366  //Lock MPC registers
367  MPC.PWPR.BIT.PFSWE = 0;
368  MPC.PWPR.BIT.B0WI = 0;
369 }
370 
371 #endif
372 
373 
374 /**
375  * @brief Initialize DMA descriptor lists
376  * @param[in] interface Underlying network interface
377  **/
378 
380 {
381  uint_t i;
382 
383  //Initialize TX descriptors
384  for(i = 0; i < RX63N_ETH_TX_BUFFER_COUNT; i++)
385  {
386  //The descriptor is initially owned by the application
387  txDmaDesc[i].td0 = 0;
388  //Transmit buffer length
389  txDmaDesc[i].td1 = 0;
390  //Transmit buffer address
391  txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
392  //Clear padding field
393  txDmaDesc[i].padding = 0;
394  }
395 
396  //Mark the last descriptor entry with the TDLE flag
397  txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
398  //Initialize TX descriptor index
399  txIndex = 0;
400 
401  //Initialize RX descriptors
402  for(i = 0; i < RX63N_ETH_RX_BUFFER_COUNT; i++)
403  {
404  //The descriptor is initially owned by the DMA
405  rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
406  //Receive buffer length
408  //Receive buffer address
409  rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
410  //Clear padding field
411  rxDmaDesc[i].padding = 0;
412  }
413 
414  //Mark the last descriptor entry with the RDLE flag
415  rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
416  //Initialize RX descriptor index
417  rxIndex = 0;
418 
419  //Start address of the TX descriptor list
420  EDMAC.TDLAR = txDmaDesc;
421  //Start address of the RX descriptor list
422  EDMAC.RDLAR = rxDmaDesc;
423 }
424 
425 
426 /**
427  * @brief RX63N Ethernet MAC timer handler
428  *
429  * This routine is periodically called by the TCP/IP stack to handle periodic
430  * operations such as polling the link state
431  *
432  * @param[in] interface Underlying network interface
433  **/
434 
435 void rx63nEthTick(NetInterface *interface)
436 {
437  //Valid Ethernet PHY or switch driver?
438  if(interface->phyDriver != NULL)
439  {
440  //Handle periodic operations
441  interface->phyDriver->tick(interface);
442  }
443  else if(interface->switchDriver != NULL)
444  {
445  //Handle periodic operations
446  interface->switchDriver->tick(interface);
447  }
448  else
449  {
450  //Just for sanity
451  }
452 }
453 
454 
455 /**
456  * @brief Enable interrupts
457  * @param[in] interface Underlying network interface
458  **/
459 
461 {
462  //Enable Ethernet MAC interrupts
463  IEN(ETHER, EINT) = 1;
464 
465  //Valid Ethernet PHY or switch driver?
466  if(interface->phyDriver != NULL)
467  {
468  //Enable Ethernet PHY interrupts
469  interface->phyDriver->enableIrq(interface);
470  }
471  else if(interface->switchDriver != NULL)
472  {
473  //Enable Ethernet switch interrupts
474  interface->switchDriver->enableIrq(interface);
475  }
476  else
477  {
478  //Just for sanity
479  }
480 }
481 
482 
483 /**
484  * @brief Disable interrupts
485  * @param[in] interface Underlying network interface
486  **/
487 
489 {
490  //Disable Ethernet MAC interrupts
491  IEN(ETHER, EINT) = 0;
492 
493  //Valid Ethernet PHY or switch driver?
494  if(interface->phyDriver != NULL)
495  {
496  //Disable Ethernet PHY interrupts
497  interface->phyDriver->disableIrq(interface);
498  }
499  else if(interface->switchDriver != NULL)
500  {
501  //Disable Ethernet switch interrupts
502  interface->switchDriver->disableIrq(interface);
503  }
504  else
505  {
506  //Just for sanity
507  }
508 }
509 
510 
511 /**
512  * @brief RX63N Ethernet MAC interrupt service routine
513  **/
514 
515 #pragma vector = VECT_ETHER_EINT
516 __interrupt void rx63nEthIrqHandler(void)
517 {
518  bool_t flag;
519  uint32_t status;
520 
521  //Allow nested interrupts
522  __enable_interrupt();
523 
524  //This flag will be set if a higher priority task must be woken
525  flag = FALSE;
526 
527  //Read interrupt status register
528  status = EDMAC.EESR.LONG;
529 
530  //Packet transmitted?
531  if((status & EDMAC_EESR_TWB) != 0)
532  {
533  //Clear TWB interrupt flag
534  EDMAC.EESR.LONG = EDMAC_EESR_TWB;
535 
536  //Check whether the TX buffer is available for writing
537  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
538  {
539  //Notify the TCP/IP stack that the transmitter is ready to send
540  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
541  }
542  }
543 
544  //Packet received?
545  if((status & EDMAC_EESR_FR) != 0)
546  {
547  //Disable FR interrupts
548  EDMAC.EESIPR.BIT.FRIP = 0;
549 
550  //Set event flag
551  nicDriverInterface->nicEvent = TRUE;
552  //Notify the TCP/IP stack of the event
553  flag |= osSetEventFromIsr(&netEvent);
554  }
555 
556  //Interrupt service routine epilogue
557  osExitIsr(flag);
558 }
559 
560 
561 /**
562  * @brief RX63N Ethernet MAC event handler
563  * @param[in] interface Underlying network interface
564  **/
565 
567 {
568  error_t error;
569 
570  //Packet received?
571  if((EDMAC.EESR.LONG & EDMAC_EESR_FR) != 0)
572  {
573  //Clear FR interrupt flag
574  EDMAC.EESR.LONG = EDMAC_EESR_FR;
575 
576  //Process all pending packets
577  do
578  {
579  //Read incoming packet
580  error = rx63nEthReceivePacket(interface);
581 
582  //No more data in the receive buffer?
583  } while(error != ERROR_BUFFER_EMPTY);
584  }
585 
586  //Re-enable EDMAC interrupts
587  EDMAC.EESIPR.BIT.TWBIP = 1;
588  EDMAC.EESIPR.BIT.FRIP = 1;
589 }
590 
591 
592 /**
593  * @brief Send a packet
594  * @param[in] interface Underlying network interface
595  * @param[in] buffer Multi-part buffer containing the data to send
596  * @param[in] offset Offset to the first data byte
597  * @param[in] ancillary Additional options passed to the stack along with
598  * the packet
599  * @return Error code
600  **/
601 
603  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
604 {
605  //Retrieve the length of the packet
606  size_t length = netBufferGetLength(buffer) - offset;
607 
608  //Check the frame length
610  {
611  //The transmitter can accept another packet
612  osSetEvent(&interface->nicTxEvent);
613  //Report an error
614  return ERROR_INVALID_LENGTH;
615  }
616 
617  //Make sure the current buffer is available for writing
618  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) != 0)
619  {
620  return ERROR_FAILURE;
621  }
622 
623  //Copy user data to the transmit buffer
624  netBufferRead(txBuffer[txIndex], buffer, offset, length);
625 
626  //Write the number of bytes to send
627  txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
628 
629  //Check current index
630  if(txIndex < (RX63N_ETH_TX_BUFFER_COUNT - 1))
631  {
632  //Give the ownership of the descriptor to the DMA engine
633  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
635 
636  //Point to the next descriptor
637  txIndex++;
638  }
639  else
640  {
641  //Give the ownership of the descriptor to the DMA engine
642  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
644 
645  //Wrap around
646  txIndex = 0;
647  }
648 
649  //Instruct the DMA to poll the transmit descriptor list
650  EDMAC.EDTRR.BIT.TR = 1;
651 
652  //Check whether the next buffer is available for writing
653  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
654  {
655  //The transmitter can accept another packet
656  osSetEvent(&interface->nicTxEvent);
657  }
658 
659  //Successful write operation
660  return NO_ERROR;
661 }
662 
663 
664 /**
665  * @brief Receive a packet
666  * @param[in] interface Underlying network interface
667  * @return Error code
668  **/
669 
671 {
672  error_t error;
673  size_t n;
674  NetRxAncillary ancillary;
675 
676  //The current buffer is available for reading?
677  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT) == 0)
678  {
679  //SOF and EOF flags should be set
680  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) != 0 &&
681  (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF) != 0)
682  {
683  //Make sure no error occurred
684  if(!(rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)))
685  {
686  //Retrieve the length of the frame
687  n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
688  //Limit the number of data to read
690 
691  //Additional options can be passed to the stack along with the packet
692  ancillary = NET_DEFAULT_RX_ANCILLARY;
693 
694  //Pass the packet to the upper layer
695  nicProcessPacket(interface, rxBuffer[rxIndex], n, &ancillary);
696 
697  //Valid packet received
698  error = NO_ERROR;
699  }
700  else
701  {
702  //The received packet contains an error
703  error = ERROR_INVALID_PACKET;
704  }
705  }
706  else
707  {
708  //The packet is not valid
709  error = ERROR_INVALID_PACKET;
710  }
711 
712  //Check current index
713  if(rxIndex < (RX63N_ETH_RX_BUFFER_COUNT - 1))
714  {
715  //Give the ownership of the descriptor back to the DMA
716  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
717  //Point to the next descriptor
718  rxIndex++;
719  }
720  else
721  {
722  //Give the ownership of the descriptor back to the DMA
723  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
724  //Wrap around
725  rxIndex = 0;
726  }
727 
728  //Instruct the DMA to poll the receive descriptor list
729  EDMAC.EDRRR.BIT.RR = 1;
730  }
731  else
732  {
733  //No more data in the receive buffer
734  error = ERROR_BUFFER_EMPTY;
735  }
736 
737  //Return status code
738  return error;
739 }
740 
741 
742 /**
743  * @brief Configure MAC address filtering
744  * @param[in] interface Underlying network interface
745  * @return Error code
746  **/
747 
749 {
750  uint_t i;
751  bool_t acceptMulticast;
752 
753  //Debug message
754  TRACE_DEBUG("Updating MAC filter...\r\n");
755 
756  //Set the upper 32 bits of the MAC address
757  ETHERC.MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
758  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
759 
760  //Set the lower 16 bits of the MAC address
761  ETHERC.MALR.BIT.MA = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
762 
763  //This flag will be set if multicast addresses should be accepted
764  acceptMulticast = FALSE;
765 
766  //The MAC address filter contains the list of MAC addresses to accept
767  //when receiving an Ethernet frame
768  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
769  {
770  //Valid entry?
771  if(interface->macAddrFilter[i].refCount > 0)
772  {
773  //Accept multicast addresses
774  acceptMulticast = TRUE;
775  //We are done
776  break;
777  }
778  }
779 
780  //Enable the reception of multicast frames if necessary
781  if(acceptMulticast)
782  {
783  EDMAC.EESR.BIT.RMAF = 1;
784  }
785  else
786  {
787  EDMAC.EESR.BIT.RMAF = 0;
788  }
789 
790  //Successful processing
791  return NO_ERROR;
792 }
793 
794 
795 /**
796  * @brief Adjust MAC configuration parameters for proper operation
797  * @param[in] interface Underlying network interface
798  * @return Error code
799  **/
800 
802 {
803  //10BASE-T or 100BASE-TX operation mode?
804  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
805  {
806  ETHERC.ECMR.BIT.RTM = 1;
807  }
808  else
809  {
810  ETHERC.ECMR.BIT.RTM = 0;
811  }
812 
813  //Half-duplex or full-duplex mode?
814  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
815  {
816  ETHERC.ECMR.BIT.DM = 1;
817  }
818  else
819  {
820  ETHERC.ECMR.BIT.DM = 0;
821  }
822 
823  //Successful processing
824  return NO_ERROR;
825 }
826 
827 
828 /**
829  * @brief Write PHY register
830  * @param[in] opcode Access type (2 bits)
831  * @param[in] phyAddr PHY address (5 bits)
832  * @param[in] regAddr Register address (5 bits)
833  * @param[in] data Register value
834  **/
835 
836 void rx63nEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
837  uint8_t regAddr, uint16_t data)
838 {
839  //Synchronization pattern
841  //Start of frame
843  //Set up a write operation
845  //Write PHY address
846  rx63nEthWriteSmi(phyAddr, 5);
847  //Write register address
849  //Turnaround
851  //Write register value
852  rx63nEthWriteSmi(data, 16);
853  //Release MDIO
854  rx63nEthReadSmi(1);
855 }
856 
857 
858 /**
859  * @brief Read PHY register
860  * @param[in] opcode Access type (2 bits)
861  * @param[in] phyAddr PHY address (5 bits)
862  * @param[in] regAddr Register address (5 bits)
863  * @return Register value
864  **/
865 
866 uint16_t rx63nEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
867  uint8_t regAddr)
868 {
869  uint16_t data;
870 
871  //Synchronization pattern
873  //Start of frame
875  //Set up a read operation
877  //Write PHY address
878  rx63nEthWriteSmi(phyAddr, 5);
879  //Write register address
881  //Turnaround to avoid contention
882  rx63nEthReadSmi(1);
883  //Read register value
884  data = rx63nEthReadSmi(16);
885  //Force the PHY to release the MDIO pin
886  rx63nEthReadSmi(1);
887 
888  //Return PHY register contents
889  return data;
890 }
891 
892 
893 /**
894  * @brief SMI write operation
895  * @param[in] data Raw data to be written
896  * @param[in] length Number of bits to be written
897  **/
898 
900 {
901  //Skip the most significant bits since they are meaningless
902  data <<= 32 - length;
903 
904  //Configure MDIO as an output
905  ETHERC.PIR.BIT.MMD = 1;
906 
907  //Write the specified number of bits
908  while(length--)
909  {
910  //Write MDIO
911  if((data & 0x80000000) != 0)
912  {
913  ETHERC.PIR.BIT.MDO = 1;
914  }
915  else
916  {
917  ETHERC.PIR.BIT.MDO = 0;
918  }
919 
920  //Assert MDC
921  usleep(1);
922  ETHERC.PIR.BIT.MDC = 1;
923  //Deassert MDC
924  usleep(1);
925  ETHERC.PIR.BIT.MDC = 0;
926 
927  //Rotate data
928  data <<= 1;
929  }
930 }
931 
932 
933 /**
934  * @brief SMI read operation
935  * @param[in] length Number of bits to be read
936  * @return Data resulting from the MDIO read operation
937  **/
938 
940 {
941  uint32_t data = 0;
942 
943  //Configure MDIO as an input
944  ETHERC.PIR.BIT.MMD = 0;
945 
946  //Read the specified number of bits
947  while(length--)
948  {
949  //Rotate data
950  data <<= 1;
951 
952  //Assert MDC
953  ETHERC.PIR.BIT.MDC = 1;
954  usleep(1);
955  //Deassert MDC
956  ETHERC.PIR.BIT.MDC = 0;
957  usleep(1);
958 
959  //Check MDIO state
960  if(ETHERC.PIR.BIT.MDI)
961  {
962  data |= 0x01;
963  }
964  }
965 
966  //Return the received data
967  return data;
968 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
__interrupt void rx63nEthIrqHandler(void)
RX63N Ethernet MAC interrupt service routine.
#define EDMAC_RD0_RACT
uint8_t length
Definition: coap_common.h:190
#define usleep(delay)
Definition: os_port.h:247
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
#define RX63N_ETH_RX_BUFFER_SIZE
#define netEvent
Definition: net_legacy.h:267
uint8_t data[]
Definition: ethernet.h:209
error_t rx63nEthInit(NetInterface *interface)
RX63N Ethernet MAC initialization.
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
void rx63nEthInitGpio(NetInterface *interface)
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:88
#define TRUE
Definition: os_port.h:50
#define sleep(delay)
Definition: os_port.h:251
void rx63nEthTick(NetInterface *interface)
RX63N Ethernet MAC timer handler.
void rx63nEthWriteSmi(uint32_t data, uint_t length)
SMI write operation.
#define SMI_TA
Definition: nic.h:67
#define EDMAC_EESR_FR
#define RX63N_ETH_RX_BUFFER_COUNT
#define SMI_START
Definition: nic.h:63
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:388
#define EDMAC_RD0_RFP_SOF
#define osExitIsr(flag)
error_t rx63nEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
#define EDMAC_TD0_TFP_EOF
#define EDMAC_TD0_TFP_SOF
#define EDMAC_RD0_RFP_EOF
#define FALSE
Definition: os_port.h:46
#define RX63N_ETH_IRQ_PRIORITY
error_t
Error codes.
Definition: error.h:42
uint32_t rx63nEthReadSmi(uint_t length)
SMI read operation.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:96
Generic error code.
Definition: error.h:45
#define EDMAC_RD0_RFS_MASK
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
Transmit DMA descriptor.
#define RX63N_ETH_TX_BUFFER_COUNT
#define NetTxAncillary
Definition: net_misc.h:36
void rx63nEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define EDMAC_TD0_TWBI
#define TRACE_INFO(...)
Definition: debug.h:95
#define EDMAC_RD1_RFL
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 rxBuffer
#define TRACE_DEBUG(...)
Definition: debug.h:107
void rx63nEthEnableIrq(NetInterface *interface)
Enable interrupts.
#define EDMAC_RD1_RBL
uint16_t regAddr
#define EDMAC_TD0_TACT
#define ETH_MTU
Definition: ethernet.h:105
uint8_t n
error_t rx63nEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void rx63nEthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define RX63N_ETH_TX_BUFFER_SIZE
#define EDMAC_RD0_RDLE
#define rxDmaDesc
#define EDMAC_TD0_TDLE
#define EDMAC_EESR_TWB
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define txDmaDesc
error_t rx63nEthReceivePacket(NetInterface *interface)
Receive a packet.
const NicDriver rx63nEthDriver
RX63N Ethernet MAC driver.
Renesas RX63N Ethernet MAC driver.
error_t rx63nEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define EDMAC_RD0_RFS_RMAF
void rx63nEthEventHandler(NetInterface *interface)
RX63N Ethernet MAC event handler.
#define SMI_SYNC
Definition: nic.h:62
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint16_t rx63nEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
NIC driver.
Definition: nic.h:257
Receive DMA descriptor.
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define EDMAC_TD1_TBL
Ethernet interface.
Definition: nic.h:82
void rx63nEthDisableIrq(NetInterface *interface)
Disable interrupts.