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