s7g2_eth2_driver.c
Go to the documentation of this file.
1 /**
2  * @file s7g2_eth2_driver.c
3  * @brief Renesas Synergy S7G2 Ethernet MAC driver (ETHERC1 instance)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "bsp_irq_cfg.h"
36 #include "s7g2.h"
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //IAR EWARM compiler?
45 #if defined(__ICCARM__)
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 //ARM or 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 S7G2 Ethernet MAC driver (ETHERC1 instance)
86  **/
87 
89 {
91  ETH_MTU,
102  TRUE,
103  TRUE,
104  TRUE,
105  TRUE
106 };
107 
108 
109 /**
110  * @brief S7G2 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 S7G2 Ethernet MAC (ETHERC1)...\r\n");
121 
122  //Save underlying network interface
123  nicDriverInterface = interface;
124 
125  //Disable protection
126  R_SYSTEM->PRCR = 0xA50B;
127  //Cancel EDMAC1 module stop state
128  R_MSTP->MSTPCRB_b.MSTPB14 = 0;
129  //Enable protection
130  R_SYSTEM->PRCR = 0xA500;
131 
132  //GPIO configuration
133  s7g2Eth2InitGpio(interface);
134 
135  //Reset EDMAC1 module
136  R_EDMAC1->EDMR |= EDMAC_EDMR_SWR;
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  s7g2Eth2InitDmaDesc(interface);
165 
166  //Maximum frame length that can be accepted
167  R_ETHERC1->RFLR = S7G2_ETH2_RX_BUFFER_SIZE;
168  //Set default inter packet gap (96-bit time)
169  R_ETHERC1->IPGR = 0x14;
170 
171  //Set the upper 32 bits of the MAC address
172  R_ETHERC1->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  R_ETHERC1->MALR = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
177 
178  //Select little endian mode and set descriptor length (16 bytes)
179  R_EDMAC1->EDMR = EDMAC_EDMR_DE | EDMAC_EDMR_DL_16;
180  //Use store and forward mode
181  R_EDMAC1->TFTR = 0;
182  //Set transmit FIFO size (2048 bytes) and receive FIFO size (4096 bytes)
183  R_EDMAC1->FDR = EDMAC_FDR_TFD_2048 | EDMAC_FDR_RFD_4096;
184  //Enable continuous reception of multiple frames
185  R_EDMAC1->RMCR = EDMAC_RMCR_RNR;
186  //Select write-back complete interrupt mode and enable transmit interrupts
187  R_EDMAC1->TRIMD = EDMAC_TRIMD_TIM | EDMAC_TRIMD_TIS;
188 
189  //Disable all ETHERC interrupts
190  R_ETHERC1->ECSIPR = 0;
191  //Enable the desired EDMAC interrupts
192  R_EDMAC1->EESIPR = EDMAC_EESIPR_TWBIP | EDMAC_EESIPR_FRIP;
193 
194  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
195  NVIC_SetPriorityGrouping(S7G2_ETH2_IRQ_PRIORITY_GROUPING);
196 
197  //Configure EDMAC interrupt priority
198  NVIC_SetPriority(EDMAC1_EINT_IRQn, NVIC_EncodePriority(S7G2_ETH2_IRQ_PRIORITY_GROUPING,
200 
201  //Enable transmission and reception
202  R_ETHERC1->ECMR |= ETHERC_ECMR_TE | ETHERC_ECMR_RE;
203 
204  //Instruct the DMA to poll the receive descriptor list
205  R_EDMAC1->EDRRR = EDMAC_EDRRR_RR;
206 
207  //Accept any packets from the upper layer
208  osSetEvent(&interface->nicTxEvent);
209 
210  //Successful initialization
211  return NO_ERROR;
212 }
213 
214 
215 /**
216  * @brief GPIO configuration
217  * @param[in] interface Underlying network interface
218  **/
219 
220 __weak_func void s7g2Eth2InitGpio(NetInterface *interface)
221 {
222 //DK-S7G2 or SK-S7G2 evaluation board?
223 #if defined(USE_DK_S7G2) || defined(USE_SK_S7G2)
224  //Disable protection
225  R_SYSTEM->PRCR = 0xA50B;
226 
227  //Disable VBATT channel 1 input (P4_3)
228  R_SYSTEM->VBTICTLR_b.VCH1INEN = 0;
229  //Disable VBATT channel 2 input (P4_4)
230  R_SYSTEM->VBTICTLR_b.VCH2INEN = 0;
231 
232  //Enable protection
233  R_SYSTEM->PRCR = 0xA500;
234 
235  //Unlock PFS registers
236  R_PMISC->PWPR_b.BOWI = 0;
237  R_PMISC->PWPR_b.PFSWE = 1;
238 
239  //Select RMII interface mode
240  R_PMISC->PFENET_b.PHYMODE1 = 0;
241 
242  //Configure ET1_MDC (P4_3)
243  R_PFS->P403PFS_b.PMR = 1;
244  R_PFS->P403PFS_b.PSEL = 23;
245  R_PFS->P403PFS_b.DSCR = 1;
246 
247  //Configure ET1_MDIO (P4_4)
248  R_PFS->P404PFS_b.PMR = 1;
249  R_PFS->P404PFS_b.PSEL = 23;
250  R_PFS->P404PFS_b.DSCR = 1;
251 
252  //Configure RMII1_TXD_EN (P4_5)
253  R_PFS->P405PFS_b.PMR = 1;
254  R_PFS->P405PFS_b.PSEL = 23;
255  R_PFS->P405PFS_b.DSCR = 3;
256 
257  //Configure RMII1_TXD1 (P4_6)
258  R_PFS->P406PFS_b.PMR = 1;
259  R_PFS->P406PFS_b.PSEL = 23;
260  R_PFS->P406PFS_b.DSCR = 3;
261 
262  //Configure RMII1_TXD0 (P7_0)
263  R_PFS->P700PFS_b.PMR = 1;
264  R_PFS->P700PFS_b.PSEL = 23;
265  R_PFS->P700PFS_b.DSCR = 3;
266 
267  //Configure REF50CK1 (P7_1)
268  R_PFS->P701PFS_b.PMR = 1;
269  R_PFS->P701PFS_b.PSEL = 23;
270  R_PFS->P701PFS_b.DSCR = 3;
271 
272  //Configure RMII1_RXD0 (P7_2)
273  R_PFS->P702PFS_b.PMR = 1;
274  R_PFS->P702PFS_b.PSEL = 23;
275  R_PFS->P702PFS_b.DSCR = 3;
276 
277  //Configure RMII1_RXD1 (P7_3)
278  R_PFS->P703PFS_b.PMR = 1;
279  R_PFS->P703PFS_b.PSEL = 23;
280  R_PFS->P703PFS_b.DSCR = 3;
281 
282  //Configure RMII1_RX_ER (P7_4)
283  R_PFS->P704PFS_b.PMR = 1;
284  R_PFS->P704PFS_b.PSEL = 23;
285  R_PFS->P704PFS_b.DSCR = 3;
286 
287  //Configure RMII1_CRS_DV (P7_5)
288  R_PFS->P705PFS_b.PMR = 1;
289  R_PFS->P705PFS_b.PSEL = 23;
290  R_PFS->P705PFS_b.DSCR = 3;
291 
292  //Lock PFS registers
293  R_PMISC->PWPR_b.PFSWE = 0;
294  R_PMISC->PWPR_b.BOWI = 1;
295 #endif
296 }
297 
298 
299 /**
300  * @brief Initialize DMA descriptor lists
301  * @param[in] interface Underlying network interface
302  **/
303 
305 {
306  uint_t i;
307 
308  //Initialize TX descriptors
309  for(i = 0; i < S7G2_ETH2_TX_BUFFER_COUNT; i++)
310  {
311  //The descriptor is initially owned by the application
312  txDmaDesc[i].td0 = 0;
313  //Transmit buffer length
314  txDmaDesc[i].td1 = 0;
315  //Transmit buffer address
316  txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
317  //Clear padding field
318  txDmaDesc[i].padding = 0;
319  }
320 
321  //Mark the last descriptor entry with the TDLE flag
322  txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
323  //Initialize TX descriptor index
324  txIndex = 0;
325 
326  //Initialize RX descriptors
327  for(i = 0; i < S7G2_ETH2_RX_BUFFER_COUNT; i++)
328  {
329  //The descriptor is initially owned by the DMA
330  rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
331  //Receive buffer length
333  //Receive buffer address
334  rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
335  //Clear padding field
336  rxDmaDesc[i].padding = 0;
337  }
338 
339  //Mark the last descriptor entry with the RDLE flag
340  rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
341  //Initialize RX descriptor index
342  rxIndex = 0;
343 
344  //Start address of the TX descriptor list
345  R_EDMAC1->TDLAR = (uint32_t) txDmaDesc;
346  //Start address of the RX descriptor list
347  R_EDMAC1->RDLAR = (uint32_t) rxDmaDesc;
348 }
349 
350 
351 /**
352  * @brief S7G2 Ethernet MAC timer handler
353  *
354  * This routine is periodically called by the TCP/IP stack to handle periodic
355  * operations such as polling the link state
356  *
357  * @param[in] interface Underlying network interface
358  **/
359 
360 void s7g2Eth2Tick(NetInterface *interface)
361 {
362  //Valid Ethernet PHY or switch driver?
363  if(interface->phyDriver != NULL)
364  {
365  //Handle periodic operations
366  interface->phyDriver->tick(interface);
367  }
368  else if(interface->switchDriver != NULL)
369  {
370  //Handle periodic operations
371  interface->switchDriver->tick(interface);
372  }
373  else
374  {
375  //Just for sanity
376  }
377 }
378 
379 
380 /**
381  * @brief Enable interrupts
382  * @param[in] interface Underlying network interface
383  **/
384 
386 {
387  //Enable Ethernet MAC interrupts
388  NVIC_EnableIRQ(EDMAC1_EINT_IRQn);
389 
390  //Valid Ethernet PHY or switch driver?
391  if(interface->phyDriver != NULL)
392  {
393  //Enable Ethernet PHY interrupts
394  interface->phyDriver->enableIrq(interface);
395  }
396  else if(interface->switchDriver != NULL)
397  {
398  //Enable Ethernet switch interrupts
399  interface->switchDriver->enableIrq(interface);
400  }
401  else
402  {
403  //Just for sanity
404  }
405 }
406 
407 
408 /**
409  * @brief Disable interrupts
410  * @param[in] interface Underlying network interface
411  **/
412 
414 {
415  //Disable Ethernet MAC interrupts
416  NVIC_DisableIRQ(EDMAC1_EINT_IRQn);
417 
418  //Valid Ethernet PHY or switch driver?
419  if(interface->phyDriver != NULL)
420  {
421  //Disable Ethernet PHY interrupts
422  interface->phyDriver->disableIrq(interface);
423  }
424  else if(interface->switchDriver != NULL)
425  {
426  //Disable Ethernet switch interrupts
427  interface->switchDriver->disableIrq(interface);
428  }
429  else
430  {
431  //Just for sanity
432  }
433 }
434 
435 
436 /**
437  * @brief S7G2 Ethernet MAC interrupt service routine
438  **/
439 
441 {
442  bool_t flag;
443  uint32_t status;
444 
445  //Interrupt service routine prologue
446  osEnterIsr();
447 
448  //This flag will be set if a higher priority task must be woken
449  flag = FALSE;
450 
451  //Read interrupt status register
452  status = R_EDMAC1->EESR;
453 
454  //Packet transmitted?
455  if((status & EDMAC_EESR_TWB) != 0)
456  {
457  //Clear TWB interrupt flag
458  R_EDMAC1->EESR = EDMAC_EESR_TWB;
459 
460  //Check whether the TX buffer is available for writing
461  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
462  {
463  //Notify the TCP/IP stack that the transmitter is ready to send
464  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
465  }
466  }
467 
468  //Packet received?
469  if((status & EDMAC_EESR_FR) != 0)
470  {
471  //Clear FR interrupt flag
472  R_EDMAC1->EESR = EDMAC_EESR_FR;
473 
474  //Set event flag
475  nicDriverInterface->nicEvent = TRUE;
476  //Notify the TCP/IP stack of the event
477  flag |= osSetEventFromIsr(&netEvent);
478  }
479 
480  //Clear IR flag
481  R_ICU->IELSRn_b[EDMAC1_EINT_IRQn].IR = 0;
482 
483  //Interrupt service routine epilogue
484  osExitIsr(flag);
485 }
486 
487 
488 /**
489  * @brief S7G2 Ethernet MAC event handler
490  * @param[in] interface Underlying network interface
491  **/
492 
494 {
495  error_t error;
496 
497  //Process all pending packets
498  do
499  {
500  //Read incoming packet
501  error = s7g2Eth2ReceivePacket(interface);
502 
503  //No more data in the receive buffer?
504  } while(error != ERROR_BUFFER_EMPTY);
505 }
506 
507 
508 /**
509  * @brief Send a packet
510  * @param[in] interface Underlying network interface
511  * @param[in] buffer Multi-part buffer containing the data to send
512  * @param[in] offset Offset to the first data byte
513  * @param[in] ancillary Additional options passed to the stack along with
514  * the packet
515  * @return Error code
516  **/
517 
519  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
520 {
521  //Retrieve the length of the packet
522  size_t length = netBufferGetLength(buffer) - offset;
523 
524  //Check the frame length
526  {
527  //The transmitter can accept another packet
528  osSetEvent(&interface->nicTxEvent);
529  //Report an error
530  return ERROR_INVALID_LENGTH;
531  }
532 
533  //Make sure the current buffer is available for writing
534  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) != 0)
535  {
536  return ERROR_FAILURE;
537  }
538 
539  //Copy user data to the transmit buffer
540  netBufferRead(txBuffer[txIndex], buffer, offset, length);
541 
542  //Write the number of bytes to send
543  txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
544 
545  //Check current index
546  if(txIndex < (S7G2_ETH2_TX_BUFFER_COUNT - 1))
547  {
548  //Give the ownership of the descriptor to the DMA engine
549  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
551 
552  //Point to the next descriptor
553  txIndex++;
554  }
555  else
556  {
557  //Give the ownership of the descriptor to the DMA engine
558  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
560 
561  //Wrap around
562  txIndex = 0;
563  }
564 
565  //Instruct the DMA to poll the transmit descriptor list
566  R_EDMAC1->EDTRR = EDMAC_EDTRR_TR;
567 
568  //Check whether the next buffer is available for writing
569  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
570  {
571  //The transmitter can accept another packet
572  osSetEvent(&interface->nicTxEvent);
573  }
574 
575  //Successful write operation
576  return NO_ERROR;
577 }
578 
579 
580 /**
581  * @brief Receive a packet
582  * @param[in] interface Underlying network interface
583  * @return Error code
584  **/
585 
587 {
588  error_t error;
589  size_t n;
590  NetRxAncillary ancillary;
591 
592  //Current buffer available for reading?
593  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT) == 0)
594  {
595  //SOF and EOF flags should be set
596  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) != 0 &&
597  (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF) != 0)
598  {
599  //Make sure no error occurred
600  if((rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)) == 0)
601  {
602  //Retrieve the length of the frame
603  n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
604  //Limit the number of data to read
606 
607  //Additional options can be passed to the stack along with the packet
608  ancillary = NET_DEFAULT_RX_ANCILLARY;
609 
610  //Pass the packet to the upper layer
611  nicProcessPacket(interface, rxBuffer[rxIndex], n, &ancillary);
612 
613  //Valid packet received
614  error = NO_ERROR;
615  }
616  else
617  {
618  //The received packet contains an error
619  error = ERROR_INVALID_PACKET;
620  }
621  }
622  else
623  {
624  //The packet is not valid
625  error = ERROR_INVALID_PACKET;
626  }
627 
628  //Check current index
629  if(rxIndex < (S7G2_ETH2_RX_BUFFER_COUNT - 1))
630  {
631  //Give the ownership of the descriptor back to the DMA
632  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
633  //Point to the next descriptor
634  rxIndex++;
635  }
636  else
637  {
638  //Give the ownership of the descriptor back to the DMA
639  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
640  //Wrap around
641  rxIndex = 0;
642  }
643 
644  //Instruct the DMA to poll the receive descriptor list
645  R_EDMAC1->EDRRR = EDMAC_EDRRR_RR;
646  }
647  else
648  {
649  //No more data in the receive buffer
650  error = ERROR_BUFFER_EMPTY;
651  }
652 
653  //Return status code
654  return error;
655 }
656 
657 
658 /**
659  * @brief Configure MAC address filtering
660  * @param[in] interface Underlying network interface
661  * @return Error code
662  **/
663 
665 {
666  uint_t i;
667  bool_t acceptMulticast;
668 
669  //Debug message
670  TRACE_DEBUG("Updating MAC filter...\r\n");
671 
672  //Promiscuous mode?
673  if(interface->promiscuous)
674  {
675  //Accept all frames regardless of their destination address
676  R_ETHERC1->ECMR |= ETHERC_ECMR_PRM;
677  }
678  else
679  {
680  //Disable promiscuous mode
681  R_ETHERC1->ECMR &= ~ETHERC_ECMR_PRM;
682 
683  //Set the upper 32 bits of the MAC address
684  R_ETHERC1->MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
685  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
686 
687  //Set the lower 16 bits of the MAC address
688  R_ETHERC1->MALR = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
689 
690  //This flag will be set if multicast addresses should be accepted
691  acceptMulticast = FALSE;
692 
693  //The MAC address filter contains the list of MAC addresses to accept
694  //when receiving an Ethernet frame
695  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
696  {
697  //Valid entry?
698  if(interface->macAddrFilter[i].refCount > 0)
699  {
700  //Accept multicast addresses
701  acceptMulticast = TRUE;
702  //We are done
703  break;
704  }
705  }
706 
707  //Enable or disable the reception of multicast frames
708  if(acceptMulticast || interface->acceptAllMulticast)
709  {
710  R_EDMAC1->EESR |= EDMAC_EESR_RMAF;
711  }
712  else
713  {
714  R_EDMAC1->EESR &= ~EDMAC_EESR_RMAF;
715  }
716  }
717 
718  //Successful processing
719  return NO_ERROR;
720 }
721 
722 
723 /**
724  * @brief Adjust MAC configuration parameters for proper operation
725  * @param[in] interface Underlying network interface
726  * @return Error code
727  **/
728 
730 {
731  uint32_t mode;
732 
733  //Read ETHERC mode register
734  mode = R_ETHERC1->ECMR;
735 
736  //10BASE-T or 100BASE-TX operation mode?
737  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
738  {
739  mode |= ETHERC_ECMR_RTM;
740  }
741  else
742  {
743  mode &= ~ETHERC_ECMR_RTM;
744  }
745 
746  //Half-duplex or full-duplex mode?
747  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
748  {
749  mode |= ETHERC_ECMR_DM;
750  }
751  else
752  {
753  mode &= ~ETHERC_ECMR_DM;
754  }
755 
756  //Update ETHERC mode register
757  R_ETHERC1->ECMR = mode;
758 
759  //Successful processing
760  return NO_ERROR;
761 }
762 
763 
764 /**
765  * @brief Write PHY register
766  * @param[in] opcode Access type (2 bits)
767  * @param[in] phyAddr PHY address (5 bits)
768  * @param[in] regAddr Register address (5 bits)
769  * @param[in] data Register value
770  **/
771 
772 void s7g2Eth2WritePhyReg(uint8_t opcode, uint8_t phyAddr,
773  uint8_t regAddr, uint16_t data)
774 {
775  //Synchronization pattern
777  //Start of frame
779  //Set up a write operation
781  //Write PHY address
782  s7g2Eth2WriteSmi(phyAddr, 5);
783  //Write register address
785  //Turnaround
787  //Write register value
788  s7g2Eth2WriteSmi(data, 16);
789  //Release MDIO
790  s7g2Eth2ReadSmi(1);
791 }
792 
793 
794 /**
795  * @brief Read PHY register
796  * @param[in] opcode Access type (2 bits)
797  * @param[in] phyAddr PHY address (5 bits)
798  * @param[in] regAddr Register address (5 bits)
799  * @return Register value
800  **/
801 
802 uint16_t s7g2Eth2ReadPhyReg(uint8_t opcode, uint8_t phyAddr,
803  uint8_t regAddr)
804 {
805  uint16_t data;
806 
807  //Synchronization pattern
809  //Start of frame
811  //Set up a read operation
813  //Write PHY address
814  s7g2Eth2WriteSmi(phyAddr, 5);
815  //Write register address
817  //Turnaround to avoid contention
818  s7g2Eth2ReadSmi(1);
819  //Read register value
820  data = s7g2Eth2ReadSmi(16);
821  //Force the PHY to release the MDIO pin
822  s7g2Eth2ReadSmi(1);
823 
824  //Return PHY register contents
825  return data;
826 }
827 
828 
829 /**
830  * @brief SMI write operation
831  * @param[in] data Raw data to be written
832  * @param[in] length Number of bits to be written
833  **/
834 
836 {
837  //Skip the most significant bits since they are meaningless
838  data <<= 32 - length;
839 
840  //Configure MDIO as an output
841  R_ETHERC1->PIR |= ETHERC_PIR_MMD;
842 
843  //Write the specified number of bits
844  while(length--)
845  {
846  //Write MDIO
847  if((data & 0x80000000) != 0)
848  {
849  R_ETHERC1->PIR |= ETHERC_PIR_MDO;
850  }
851  else
852  {
853  R_ETHERC1->PIR &= ~ETHERC_PIR_MDO;
854  }
855 
856  //Assert MDC
857  usleep(1);
858  R_ETHERC1->PIR |= ETHERC_PIR_MDC;
859  //Deassert MDC
860  usleep(1);
861  R_ETHERC1->PIR &= ~ETHERC_PIR_MDC;
862 
863  //Rotate data
864  data <<= 1;
865  }
866 }
867 
868 
869 /**
870  * @brief SMI read operation
871  * @param[in] length Number of bits to be read
872  * @return Data resulting from the MDIO read operation
873  **/
874 
876 {
877  uint32_t data = 0;
878 
879  //Configure MDIO as an input
880  R_ETHERC1->PIR &= ~ETHERC_PIR_MMD;
881 
882  //Read the specified number of bits
883  while(length--)
884  {
885  //Rotate data
886  data <<= 1;
887 
888  //Assert MDC
889  R_ETHERC1->PIR |= ETHERC_PIR_MDC;
890  usleep(1);
891  //Deassert MDC
892  R_ETHERC1->PIR &= ~ETHERC_PIR_MDC;
893  usleep(1);
894 
895  //Check MDIO state
896  if((R_ETHERC1->PIR & ETHERC_PIR_MDI) != 0)
897  {
898  data |= 0x01;
899  }
900  }
901 
902  //Return the received data
903  return data;
904 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define EDMAC_RD0_RFP_EOF
void s7g2Eth2Tick(NetInterface *interface)
S7G2 Ethernet MAC timer handler.
void s7g2Eth2EnableIrq(NetInterface *interface)
Enable interrupts.
#define usleep(delay)
Definition: os_port.h:303
void s7g2Eth2WritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
uint8_t opcode
Definition: dns_common.h:188
#define S7G2_ETH2_IRQ_SUB_PRIORITY
int bool_t
Definition: compiler_port.h:53
#define netEvent
Definition: net_legacy.h:196
#define EDMAC_EDTRR_TR
#define EDMAC_EESR_TWB
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
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
void s7g2Eth2InitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
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:307
#define EDMAC_RD0_RACT
#define ETHERC_ECMR_PRM
#define EDMAC_EDMR_DL_16
#define SMI_TA
Definition: nic.h:68
#define SMI_START
Definition: nic.h:64
void s7g2Eth2EventHandler(NetInterface *interface)
S7G2 Ethernet MAC event handler.
#define ETHERC_PIR_MDO
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 ETHERC_PIR_MDC
#define osExitIsr(flag)
#define EDMAC_TD0_TWBI
#define EDMAC_EDMR_SWR
#define ETHERC_ECMR_RTM
#define EDMAC_EESIPR_TWBIP
#define EDMAC_RD1_RFL
#define EDMAC_EESR_RMAF
#define EDMAC_RMCR_RNR
#define EDMAC_EDMR_DE
#define EDMAC_RD0_RDLE
#define EDMAC_EESIPR_FRIP
#define FALSE
Definition: os_port.h:46
error_t s7g2Eth2Init(NetInterface *interface)
S7G2 Ethernet MAC initialization.
#define EDMAC_RD0_RFP_SOF
error_t
Error codes.
Definition: error.h:43
#define EDMAC_RD1_RBL
void s7g2Eth2WriteSmi(uint32_t data, uint_t length)
SMI write operation.
#define ETHERC_ECMR_DM
void s7g2Eth2DisableIrq(NetInterface *interface)
Disable interrupts.
#define ETHERC_ECMR_RE
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:104
@ 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:140
#define NetInterface
Definition: net.h:36
#define S7G2_ETH2_RX_BUFFER_SIZE
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define EDMAC_RD0_RFS_MASK
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
uint32_t s7g2Eth2ReadSmi(uint_t length)
SMI read operation.
#define ETHERC_ECMR_TE
#define EDMAC_TRIMD_TIS
#define ETHERC_PIR_MMD
#define EDMAC_FDR_TFD_2048
#define NetTxAncillary
Definition: net_misc.h:36
#define S7G2_ETH2_TX_BUFFER_SIZE
Renesas Synergy S7G2 Ethernet MAC driver (ETHERC1 instance)
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
error_t s7g2Eth2UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define MIN(a, b)
Definition: os_port.h:63
#define rxBuffer
#define S7G2_ETH2_IRQ_PRIORITY_GROUPING
#define EDMAC_TD1_TBL
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define S7G2_ETH2_IRQ_GROUP_PRIORITY
#define EDMAC_TD0_TFP_SOF
#define EDMAC_TD0_TDLE
#define S7G2_ETH2_TX_BUFFER_COUNT
#define EDMAC_EDRRR_RR
Transmit DMA descriptor.
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:116
uint8_t n
error_t s7g2Eth2SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
#define osEnterIsr()
#define EDMAC_EESR_FR
#define EDMAC_TRIMD_TIM
#define S7G2_ETH2_RX_BUFFER_COUNT
#define rxDmaDesc
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
Receive DMA descriptor.
#define txDmaDesc
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define EDMAC_TD0_TACT
__weak_func void s7g2Eth2InitGpio(NetInterface *interface)
GPIO configuration.
#define SMI_SYNC
Definition: nic.h:63
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
error_t s7g2Eth2ReceivePacket(NetInterface *interface)
Receive a packet.
NIC driver.
Definition: nic.h:286
void EDMAC1_EINT_IRQHandler(void)
S7G2 Ethernet MAC interrupt service routine.
error_t s7g2Eth2UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint16_t s7g2Eth2ReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define ETHERC_PIR_MDI
const NicDriver s7g2Eth2Driver
S7G2 Ethernet MAC driver (ETHERC1 instance)
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define EDMAC_FDR_RFD_4096
#define EDMAC_TD0_TFP_EOF
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83