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