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