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