rza1_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file rza1_eth_driver.c
3  * @brief Renesas RZ/A1 Ethernet MAC driver
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 "iodefine.h"
36 #include "cpg_iobitmask.h"
37 #include "intc.h"
38 #include "core/net.h"
40 #include "debug.h"
41 
42 //Underlying network interface
43 static NetInterface *nicDriverInterface;
44 
45 //IAR EWARM compiler?
46 #if defined(__ICCARM__)
47 
48 //Transmit buffer
49 #pragma data_alignment = 32
50 #pragma location = RZA1_ETH_RAM_SECTION
52 //Receive buffer
53 #pragma data_alignment = 32
54 #pragma location = RZA1_ETH_RAM_SECTION
56 //Transmit DMA descriptors
57 #pragma data_alignment = 32
58 #pragma location = RZA1_ETH_RAM_SECTION
60 //Receive DMA descriptors
61 #pragma data_alignment = 32
62 #pragma location = RZA1_ETH_RAM_SECTION
64 
65 //ARM or GCC compiler?
66 #else
67 
68 //Transmit buffer
70  __attribute__((aligned(32), section(RZA1_ETH_RAM_SECTION)));
71 //Receive buffer
73  __attribute__((aligned(32), section(RZA1_ETH_RAM_SECTION)));
74 //Transmit DMA descriptors
76  __attribute__((aligned(32), section(RZA1_ETH_RAM_SECTION)));
77 //Receive DMA descriptors
79  __attribute__((aligned(32), section(RZA1_ETH_RAM_SECTION)));
80 
81 #endif
82 
83 //Current transmit descriptor
84 static uint_t txIndex;
85 //Current receive descriptor
86 static uint_t rxIndex;
87 
88 
89 /**
90  * @brief RZ/A1 Ethernet MAC driver
91  **/
92 
94 {
96  ETH_MTU,
107  TRUE,
108  TRUE,
109  TRUE,
110  TRUE
111 };
112 
113 
114 /**
115  * @brief RZ/A1 Ethernet MAC initialization
116  * @param[in] interface Underlying network interface
117  * @return Error code
118  **/
119 
121 {
122  error_t error;
123 
124  //Debug message
125  TRACE_INFO("Initializing RZ/A1 Ethernet MAC...\r\n");
126 
127  //Save underlying network interface
128  nicDriverInterface = interface;
129 
130  //Enable Ethernet peripheral clock
131  CPG.STBCR7 &= ~CPG_STBCR7_MSTP74;
132 
133  //GPIO configuration
134  rza1EthInitGpio(interface);
135 
136  //Perform software reset
137  ETHER.ARSTR = ETHER_ARSTR_ARST;
138  //Wait for the reset to complete
139  sleep(10);
140 
141  //Start EDMAC transmitting and receiving units
142  ETHER.EDSR0 = ETHER_EDSR0_ENT | ETHER_EDSR0_ENR;
143 
144  //To execute a software reset with this register, 1 must be written to
145  //both the SWRT and SWRR bits simultaneously
146  ETHER.EDMR0 = ETHER_EDMR0_SWRT | ETHER_EDMR0_SWRR;
147 
148  //Wait for the reset to complete
149  while((ETHER.EDMR0 & (ETHER_EDMR0_SWRT | ETHER_EDMR0_SWRR)) != 0)
150  {
151  }
152 
153  //Valid Ethernet PHY or switch driver?
154  if(interface->phyDriver != NULL)
155  {
156  //Ethernet PHY initialization
157  error = interface->phyDriver->init(interface);
158  }
159  else if(interface->switchDriver != NULL)
160  {
161  //Ethernet switch initialization
162  error = interface->switchDriver->init(interface);
163  }
164  else
165  {
166  //The interface is not properly configured
167  error = ERROR_FAILURE;
168  }
169 
170  //Any error to report?
171  if(error)
172  {
173  return error;
174  }
175 
176  //Initialize DMA descriptor lists
177  rza1EthInitDmaDesc(interface);
178 
179  //Select little endian mode and set descriptor length (16 bytes)
180  ETHER.EDMR0 = ETHER_EDMR0_DE | ETHER_EDMR0_DL_16;
181 
182  //Error masks
183  ETHER.TRSCER0 = 0;
184  //Use store and forward mode
185  ETHER.TFTR0 = 0;
186 
187  //Set transmit FIFO size and receive FIFO size (2048 bytes)
189 
190  //Enable continuous reception of multiple frames
191  ETHER.RMCR0 = ETHER_RMCR0_RNC;
192  //No padding insertion into receive data
193  ETHER.RPADIR0 = 0;
194 
195  //Receive FIFO threshold (8 frames or 2048-64 bytes)
196  ETHER.FCFTR0 = ETHER_FCFTR0_RFF_8 | ETHER_FCFTR0_RFD_2048;
197 
198  //Intelligent checksum operation mode
199  ETHER.CSMR = 0;
200 
201  //Enable multicast address filtering
202  ETHER.ECMR0 |= ETHER_ECMR0_MCT;
203 
204  //Set the upper 32 bits of the MAC address
205  ETHER.MAHR0 = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
206  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
207 
208  //Set the lower 16 bits of the MAC address
209  ETHER.MALR0 = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
210 
211  //Disable all CAM entries
212  ETHER.TSU_TEN = 0;
213 
214  //Maximum frame length that can be accepted
215  ETHER.RFLR0 = RZA1_ETH_RX_BUFFER_SIZE;
216  //Automatic pause frame
217  ETHER.APR0 = 0;
218  //Manual pause frame
219  ETHER.MPR0 = 0;
220  //Automatic pause frame retransmit count
221  ETHER.TPAUSER0 = 0;
222 
223  //Disable all EMAC interrupts
224  ETHER.ECSIPR0 = 0;
225 
226  //Enable the desired EDMAC interrupts
227  ETHER.EESIPR0 = ETHER_EESIPR0_TWBIP | ETHER_EESIPR0_FRIP;
228 
229  //Register interrupt handler
230  R_INTC_Regist_Int_Func(INTC_ID_ETHERI, rza1EthIrqHandler);
231  //Configure interrupt priority
232  R_INTC_Set_Priority(INTC_ID_ETHERI, RZA1_ETH_IRQ_PRIORITY);
233 
234  //Enable transmission and reception
235  ETHER.ECMR0 |= ETHER_ECMR0_TE | ETHER_ECMR0_RE;
236 
237  //Instruct the DMA to poll the receive descriptor list
238  ETHER.EDRRR0 = ETHER_EDRRR0_RR;
239 
240  //Accept any packets from the upper layer
241  osSetEvent(&interface->nicTxEvent);
242 
243  //Successful initialization
244  return NO_ERROR;
245 }
246 
247 
248 /**
249  * @brief GPIO configuration
250  * @param[in] interface Underlying network interface
251  **/
252 
253 __weak_func void rza1EthInitGpio(NetInterface *interface)
254 {
255 //RSK RZ/A1H or Hachiko evaluation board?
256 #if defined(USE_RSK_RZA1H) || defined(USE_HACHIKO)
257  //Configure ET_COL (P1_14)
258  PORT1.PMCn.BIT.PMCn14 = 1;
259  PORT1.PFCn.BIT.PFCn14 = 1;
260  PORT1.PFCEn.BIT.PFCEn14 = 1;
261  PORT1.PFCAEn.BIT.PFCAEn14 = 0;
262  PORT1.PIPCn.BIT.PIPCn14 = 1;
263 
264  //Configure ET_TXCLK (P2_0)
265  PORT2.PMCn.BIT.PMCn0 = 1;
266  PORT2.PFCn.BIT.PFCn0 = 1;
267  PORT2.PFCEn.BIT.PFCEn0 = 0;
268  PORT2.PFCAEn.BIT.PFCAEn0 = 0;
269  PORT2.PIPCn.BIT.PIPCn0 = 1;
270 
271  //Configure ET_TXER (P2_1)
272  PORT2.PMCn.BIT.PMCn1 = 1;
273  PORT2.PFCn.BIT.PFCn1 = 1;
274  PORT2.PFCEn.BIT.PFCEn1 = 0;
275  PORT2.PFCAEn.BIT.PFCAEn1 = 0;
276  PORT2.PIPCn.BIT.PIPCn1 = 1;
277 
278  //Configure ET_TXEN (P2_2)
279  PORT2.PMCn.BIT.PMCn2 = 1;
280  PORT2.PFCn.BIT.PFCn2 = 1;
281  PORT2.PFCEn.BIT.PFCEn2 = 0;
282  PORT2.PFCAEn.BIT.PFCAEn2 = 0;
283  PORT2.PIPCn.BIT.PIPCn2 = 1;
284 
285  //Configure ET_CRS (P2_3)
286  PORT2.PMCn.BIT.PMCn3 = 1;
287  PORT2.PFCn.BIT.PFCn3 = 1;
288  PORT2.PFCEn.BIT.PFCEn3 = 0;
289  PORT2.PFCAEn.BIT.PFCAEn3 = 0;
290  PORT2.PIPCn.BIT.PIPCn3 = 1;
291 
292  //Configure ET_TXD0 (P2_4)
293  PORT2.PMCn.BIT.PMCn4 = 1;
294  PORT2.PFCn.BIT.PFCn4 = 1;
295  PORT2.PFCEn.BIT.PFCEn4 = 0;
296  PORT2.PFCAEn.BIT.PFCAEn4 = 0;
297  PORT2.PIPCn.BIT.PIPCn4 = 1;
298 
299  //Configure ET_TXD1 (P2_5)
300  PORT2.PMCn.BIT.PMCn5 = 1;
301  PORT2.PFCn.BIT.PFCn5 = 1;
302  PORT2.PFCEn.BIT.PFCEn5 = 0;
303  PORT2.PFCAEn.BIT.PFCAEn5 = 0;
304  PORT2.PIPCn.BIT.PIPCn5 = 1;
305 
306  //Configure ET_TXD2 (P2_6)
307  PORT2.PMCn.BIT.PMCn6 = 1;
308  PORT2.PFCn.BIT.PFCn6 = 1;
309  PORT2.PFCEn.BIT.PFCEn6 = 0;
310  PORT2.PFCAEn.BIT.PFCAEn6 = 0;
311  PORT2.PIPCn.BIT.PIPCn6 = 1;
312 
313  //Configure ET_TXD3 (P2_7)
314  PORT2.PMCn.BIT.PMCn7 = 1;
315  PORT2.PFCn.BIT.PFCn7 = 1;
316  PORT2.PFCEn.BIT.PFCEn7 = 0;
317  PORT2.PFCAEn.BIT.PFCAEn7 = 0;
318  PORT2.PIPCn.BIT.PIPCn7 = 1;
319 
320  //Configure ET_RXD0 (P2_8)
321  PORT2.PMCn.BIT.PMCn8 = 1;
322  PORT2.PFCn.BIT.PFCn8 = 1;
323  PORT2.PFCEn.BIT.PFCEn8 = 0;
324  PORT2.PFCAEn.BIT.PFCAEn8 = 0;
325  PORT2.PIPCn.BIT.PIPCn8 = 1;
326 
327  //Configure ET_RXD1 (P2_9)
328  PORT2.PMCn.BIT.PMCn9 = 1;
329  PORT2.PFCn.BIT.PFCn9 = 1;
330  PORT2.PFCEn.BIT.PFCEn9 = 0;
331  PORT2.PFCAEn.BIT.PFCAEn9 = 0;
332  PORT2.PIPCn.BIT.PIPCn9 = 1;
333 
334  //Configure ET_RXD2 (P2_10)
335  PORT2.PMCn.BIT.PMCn10 = 1;
336  PORT2.PFCn.BIT.PFCn10 = 1;
337  PORT2.PFCEn.BIT.PFCEn10 = 0;
338  PORT2.PFCAEn.BIT.PFCAEn10 = 0;
339  PORT2.PIPCn.BIT.PIPCn10 = 1;
340 
341  //Configure ET_RXD3 (P2_11)
342  PORT2.PMCn.BIT.PMCn11 = 1;
343  PORT2.PFCn.BIT.PFCn11 = 1;
344  PORT2.PFCEn.BIT.PFCEn11 = 0;
345  PORT2.PFCAEn.BIT.PFCAEn11 = 0;
346  PORT2.PIPCn.BIT.PIPCn11 = 1;
347 
348  //Configure ET_MDIO (P3_3)
349  PORT3.PMCn.BIT.PMCn3 = 1;
350  PORT3.PFCn.BIT.PFCn3 = 1;
351  PORT3.PFCEn.BIT.PFCEn3 = 0;
352  PORT3.PFCAEn.BIT.PFCAEn3 = 0;
353  PORT3.PIPCn.BIT.PIPCn3 = 1;
354 
355  //Configure ET_RXCLK (P3_4)
356  PORT3.PMCn.BIT.PMCn4 = 1;
357  PORT3.PFCn.BIT.PFCn4 = 1;
358  PORT3.PFCEn.BIT.PFCEn4 = 0;
359  PORT3.PFCAEn.BIT.PFCAEn4 = 0;
360  PORT3.PIPCn.BIT.PIPCn4 = 1;
361 
362  //Configure ET_RXER (P3_5)
363  PORT3.PMCn.BIT.PMCn5 = 1;
364  PORT3.PFCn.BIT.PFCn5 = 1;
365  PORT3.PFCEn.BIT.PFCEn5 = 0;
366  PORT3.PFCAEn.BIT.PFCAEn5 = 0;
367  PORT3.PIPCn.BIT.PIPCn5 = 1;
368 
369  //Configure ET_RXDV (P3_6)
370  PORT3.PMCn.BIT.PMCn6 = 1;
371  PORT3.PFCn.BIT.PFCn6 = 1;
372  PORT3.PFCEn.BIT.PFCEn6 = 0;
373  PORT3.PFCAEn.BIT.PFCAEn6 = 0;
374  PORT3.PIPCn.BIT.PIPCn6 = 1;
375 
376  //Configure ET_MDC (P5_9)
377  PORT5.PMCn.BIT.PMCn9 = 1;
378  PORT5.PFCn.BIT.PFCn9 = 1;
379  PORT5.PFCEn.BIT.PFCEn9 = 0;
380  PORT5.PFCAEn.BIT.PFCAEn9 = 0;
381  PORT5.PIPCn.BIT.PIPCn9 = 1;
382 
383 //VK-RZ/A1H evaluation board?
384 #elif defined(USE_VK_RZA1H)
385  //Configure ET_COL (P1_14)
386  PORT1.PMCn.BIT.PMCn14 = 1;
387  PORT1.PFCn.BIT.PFCn14 = 1;
388  PORT1.PFCEn.BIT.PFCEn14 = 1;
389  PORT1.PFCAEn.BIT.PFCAEn14 = 0;
390  PORT1.PIPCn.BIT.PIPCn14 = 1;
391 
392  //Configure ET_TXCLK (P2_0)
393  PORT2.PMCn.BIT.PMCn0 = 1;
394  PORT2.PFCn.BIT.PFCn0 = 1;
395  PORT2.PFCEn.BIT.PFCEn0 = 0;
396  PORT2.PFCAEn.BIT.PFCAEn0 = 0;
397  PORT2.PIPCn.BIT.PIPCn0 = 1;
398 
399  //Configure ET_TXER (P2_1)
400  PORT2.PMCn.BIT.PMCn1 = 1;
401  PORT2.PFCn.BIT.PFCn1 = 1;
402  PORT2.PFCEn.BIT.PFCEn1 = 0;
403  PORT2.PFCAEn.BIT.PFCAEn1 = 0;
404  PORT2.PIPCn.BIT.PIPCn1 = 1;
405 
406  //Configure ET_TXEN (P2_2)
407  PORT2.PMCn.BIT.PMCn2 = 1;
408  PORT2.PFCn.BIT.PFCn2 = 1;
409  PORT2.PFCEn.BIT.PFCEn2 = 0;
410  PORT2.PFCAEn.BIT.PFCAEn2 = 0;
411  PORT2.PIPCn.BIT.PIPCn2 = 1;
412 
413  //Configure ET_CRS (P2_3)
414  PORT2.PMCn.BIT.PMCn3 = 1;
415  PORT2.PFCn.BIT.PFCn3 = 1;
416  PORT2.PFCEn.BIT.PFCEn3 = 0;
417  PORT2.PFCAEn.BIT.PFCAEn3 = 0;
418  PORT2.PIPCn.BIT.PIPCn3 = 1;
419 
420  //Configure ET_TXD0 (P2_4)
421  PORT2.PMCn.BIT.PMCn4 = 1;
422  PORT2.PFCn.BIT.PFCn4 = 1;
423  PORT2.PFCEn.BIT.PFCEn4 = 0;
424  PORT2.PFCAEn.BIT.PFCAEn4 = 0;
425  PORT2.PIPCn.BIT.PIPCn4 = 1;
426 
427  //Configure ET_TXD1 (P2_5)
428  PORT2.PMCn.BIT.PMCn5 = 1;
429  PORT2.PFCn.BIT.PFCn5 = 1;
430  PORT2.PFCEn.BIT.PFCEn5 = 0;
431  PORT2.PFCAEn.BIT.PFCAEn5 = 0;
432  PORT2.PIPCn.BIT.PIPCn5 = 1;
433 
434  //Configure ET_TXD2 (P2_6)
435  PORT2.PMCn.BIT.PMCn6 = 1;
436  PORT2.PFCn.BIT.PFCn6 = 1;
437  PORT2.PFCEn.BIT.PFCEn6 = 0;
438  PORT2.PFCAEn.BIT.PFCAEn6 = 0;
439  PORT2.PIPCn.BIT.PIPCn6 = 1;
440 
441  //Configure ET_TXD3 (P2_7)
442  PORT2.PMCn.BIT.PMCn7 = 1;
443  PORT2.PFCn.BIT.PFCn7 = 1;
444  PORT2.PFCEn.BIT.PFCEn7 = 0;
445  PORT2.PFCAEn.BIT.PFCAEn7 = 0;
446  PORT2.PIPCn.BIT.PIPCn7 = 1;
447 
448  //Configure ET_RXD0 (P2_8)
449  PORT2.PMCn.BIT.PMCn8 = 1;
450  PORT2.PFCn.BIT.PFCn8 = 1;
451  PORT2.PFCEn.BIT.PFCEn8 = 0;
452  PORT2.PFCAEn.BIT.PFCAEn8 = 0;
453  PORT2.PIPCn.BIT.PIPCn8 = 1;
454 
455  //Configure ET_RXD1 (P2_9)
456  PORT2.PMCn.BIT.PMCn9 = 1;
457  PORT2.PFCn.BIT.PFCn9 = 1;
458  PORT2.PFCEn.BIT.PFCEn9 = 0;
459  PORT2.PFCAEn.BIT.PFCAEn9 = 0;
460  PORT2.PIPCn.BIT.PIPCn9 = 1;
461 
462  //Configure ET_RXD2 (P2_10)
463  PORT2.PMCn.BIT.PMCn10 = 1;
464  PORT2.PFCn.BIT.PFCn10 = 1;
465  PORT2.PFCEn.BIT.PFCEn10 = 0;
466  PORT2.PFCAEn.BIT.PFCAEn10 = 0;
467  PORT2.PIPCn.BIT.PIPCn10 = 1;
468 
469  //Configure ET_RXD3 (P2_11)
470  PORT2.PMCn.BIT.PMCn11 = 1;
471  PORT2.PFCn.BIT.PFCn11 = 1;
472  PORT2.PFCEn.BIT.PFCEn11 = 0;
473  PORT2.PFCAEn.BIT.PFCAEn11 = 0;
474  PORT2.PIPCn.BIT.PIPCn11 = 1;
475 
476  //Configure ET_MDIO (P3_3)
477  PORT3.PMCn.BIT.PMCn3 = 1;
478  PORT3.PFCn.BIT.PFCn3 = 1;
479  PORT3.PFCEn.BIT.PFCEn3 = 0;
480  PORT3.PFCAEn.BIT.PFCAEn3 = 0;
481  PORT3.PIPCn.BIT.PIPCn3 = 1;
482 
483  //Configure ET_RXCLK (P3_4)
484  PORT3.PMCn.BIT.PMCn4 = 1;
485  PORT3.PFCn.BIT.PFCn4 = 1;
486  PORT3.PFCEn.BIT.PFCEn4 = 0;
487  PORT3.PFCAEn.BIT.PFCAEn4 = 0;
488  PORT3.PIPCn.BIT.PIPCn4 = 1;
489 
490  //Configure ET_RXER (P3_5)
491  PORT3.PMCn.BIT.PMCn5 = 1;
492  PORT3.PFCn.BIT.PFCn5 = 1;
493  PORT3.PFCEn.BIT.PFCEn5 = 0;
494  PORT3.PFCAEn.BIT.PFCAEn5 = 0;
495  PORT3.PIPCn.BIT.PIPCn5 = 1;
496 
497  //Configure ET_RXDV (P3_6)
498  PORT3.PMCn.BIT.PMCn6 = 1;
499  PORT3.PFCn.BIT.PFCn6 = 1;
500  PORT3.PFCEn.BIT.PFCEn6 = 0;
501  PORT3.PFCAEn.BIT.PFCAEn6 = 0;
502  PORT3.PIPCn.BIT.PIPCn6 = 1;
503 
504  //Configure ET_MDC (P7_0)
505  PORT7.PMCn.BIT.PMCn0 = 1;
506  PORT7.PFCn.BIT.PFCn0 = 0;
507  PORT7.PFCEn.BIT.PFCEn0 = 1;
508  PORT7.PFCAEn.BIT.PFCAEn0 = 0;
509  PORT7.PIPCn.BIT.PIPCn0 = 1;
510 
511 //Stream it! RZ evaluation board?
512 #elif defined(USE_STREAM_IT_RZ)
513  //Configure ET_TXD0 (P8_0)
514  PORT8.PMCn.BIT.PMCn0 = 1;
515  PORT8.PFCn.BIT.PFCn0 = 1;
516  PORT8.PFCEn.BIT.PFCEn0 = 0;
517  PORT8.PFCAEn.BIT.PFCAEn0 = 0;
518  PORT8.PIPCn.BIT.PIPCn0 = 1;
519 
520  //Configure ET_TXD1 (P8_1)
521  PORT8.PMCn.BIT.PMCn1 = 1;
522  PORT8.PFCn.BIT.PFCn1 = 1;
523  PORT8.PFCEn.BIT.PFCEn1 = 0;
524  PORT8.PFCAEn.BIT.PFCAEn1 = 0;
525  PORT8.PIPCn.BIT.PIPCn1 = 1;
526 
527  //Configure ET_TXD2 (P8_2)
528  PORT8.PMCn.BIT.PMCn2 = 1;
529  PORT8.PFCn.BIT.PFCn2 = 1;
530  PORT8.PFCEn.BIT.PFCEn2 = 0;
531  PORT8.PFCAEn.BIT.PFCAEn2 = 0;
532  PORT8.PIPCn.BIT.PIPCn2 = 1;
533 
534  //Configure ET_TXD3 (P8_3)
535  PORT8.PMCn.BIT.PMCn3 = 1;
536  PORT8.PFCn.BIT.PFCn3 = 1;
537  PORT8.PFCEn.BIT.PFCEn3 = 0;
538  PORT8.PFCAEn.BIT.PFCAEn3 = 0;
539  PORT8.PIPCn.BIT.PIPCn3 = 1;
540 
541  //Configure ET_TXCLK (P8_4)
542  PORT8.PMCn.BIT.PMCn4 = 1;
543  PORT8.PFCn.BIT.PFCn4 = 1;
544  PORT8.PFCEn.BIT.PFCEn4 = 0;
545  PORT8.PFCAEn.BIT.PFCAEn4 = 0;
546  PORT8.PIPCn.BIT.PIPCn4 = 1;
547 
548  //Configure ET_TXER (P8_5)
549  PORT8.PMCn.BIT.PMCn5 = 1;
550  PORT8.PFCn.BIT.PFCn5 = 1;
551  PORT8.PFCEn.BIT.PFCEn5 = 0;
552  PORT8.PFCAEn.BIT.PFCAEn5 = 0;
553  PORT8.PIPCn.BIT.PIPCn5 = 1;
554 
555  //Configure ET_TXEN (P8_6)
556  PORT8.PMCn.BIT.PMCn6 = 1;
557  PORT8.PFCn.BIT.PFCn6 = 1;
558  PORT8.PFCEn.BIT.PFCEn6 = 0;
559  PORT8.PFCAEn.BIT.PFCAEn6 = 0;
560  PORT8.PIPCn.BIT.PIPCn6 = 1;
561 
562  //Configure ET_RXD0 (P8_7)
563  PORT8.PMCn.BIT.PMCn7 = 1;
564  PORT8.PFCn.BIT.PFCn7 = 1;
565  PORT8.PFCEn.BIT.PFCEn7 = 0;
566  PORT8.PFCAEn.BIT.PFCAEn7 = 0;
567  PORT8.PIPCn.BIT.PIPCn7 = 1;
568 
569  //Configure ET_RXD1 (P8_8)
570  PORT8.PMCn.BIT.PMCn8 = 1;
571  PORT8.PFCn.BIT.PFCn8 = 1;
572  PORT8.PFCEn.BIT.PFCEn8 = 0;
573  PORT8.PFCAEn.BIT.PFCAEn8 = 0;
574  PORT8.PIPCn.BIT.PIPCn8 = 1;
575 
576  //Configure ET_RXD2 (P8_9)
577  PORT8.PMCn.BIT.PMCn9 = 1;
578  PORT8.PFCn.BIT.PFCn9 = 1;
579  PORT8.PFCEn.BIT.PFCEn9 = 0;
580  PORT8.PFCAEn.BIT.PFCAEn9 = 0;
581  PORT8.PIPCn.BIT.PIPCn9 = 1;
582 
583  //Configure ET_RXD3 (P8_10)
584  PORT8.PMCn.BIT.PMCn10 = 1;
585  PORT8.PFCn.BIT.PFCn10 = 1;
586  PORT8.PFCEn.BIT.PFCEn10 = 0;
587  PORT8.PFCAEn.BIT.PFCAEn10 = 0;
588  PORT8.PIPCn.BIT.PIPCn10 = 1;
589 
590  //Configure ET_COL (P8_14)
591  PORT8.PMCn.BIT.PMCn14 = 1;
592  PORT8.PFCn.BIT.PFCn14 = 1;
593  PORT8.PFCEn.BIT.PFCEn14 = 0;
594  PORT8.PFCAEn.BIT.PFCAEn14 = 0;
595  PORT8.PIPCn.BIT.PIPCn14 = 1;
596 
597  //Configure ET_CRS (P8_15)
598  PORT8.PMCn.BIT.PMCn15 = 1;
599  PORT8.PFCn.BIT.PFCn15 = 1;
600  PORT8.PFCEn.BIT.PFCEn15 = 0;
601  PORT8.PFCAEn.BIT.PFCAEn15 = 0;
602  PORT8.PIPCn.BIT.PIPCn15 = 1;
603 
604  //Configure ET_MDC (P9_0)
605  PORT9.PMCn.BIT.PMCn0 = 1;
606  PORT9.PFCn.BIT.PFCn0 = 1;
607  PORT9.PFCEn.BIT.PFCEn0 = 0;
608  PORT9.PFCAEn.BIT.PFCAEn0 = 0;
609  PORT9.PIPCn.BIT.PIPCn0 = 1;
610 
611  //Configure ET_MDIO (P9_1)
612  PORT9.PMCn.BIT.PMCn1 = 1;
613  PORT9.PFCn.BIT.PFCn1 = 1;
614  PORT9.PFCEn.BIT.PFCEn1 = 0;
615  PORT9.PFCAEn.BIT.PFCAEn1 = 0;
616  PORT9.PIPCn.BIT.PIPCn1 = 1;
617 
618  //Configure ET_RXCLK (P9_2)
619  PORT9.PMCn.BIT.PMCn2 = 1;
620  PORT9.PFCn.BIT.PFCn2 = 1;
621  PORT9.PFCEn.BIT.PFCEn2 = 0;
622  PORT9.PFCAEn.BIT.PFCAEn2 = 0;
623  PORT9.PIPCn.BIT.PIPCn2 = 1;
624 
625  //Configure ET_RXER (P9_3)
626  PORT9.PMCn.BIT.PMCn3 = 1;
627  PORT9.PFCn.BIT.PFCn3 = 1;
628  PORT9.PFCEn.BIT.PFCEn3 = 0;
629  PORT9.PFCAEn.BIT.PFCAEn3 = 0;
630  PORT9.PIPCn.BIT.PIPCn3 = 1;
631 
632  //Configure ET_RXDV (P9_4)
633  PORT9.PMCn.BIT.PMCn4 = 1;
634  PORT9.PFCn.BIT.PFCn4 = 1;
635  PORT9.PFCEn.BIT.PFCEn4 = 0;
636  PORT9.PFCAEn.BIT.PFCAEn4 = 0;
637  PORT9.PIPCn.BIT.PIPCn4 = 1;
638 
639  //Configure PHY_RST (P2_7)
640  PORT2.PMCn.BIT.PMCn7 = 0;
641  PORT2.PIPCn.BIT.PIPCn7 = 0;
642  PORT2.PMn.BIT.PMn7 = 0;
643 
644  //Reset the PHY transceiver
645  PORT2.Pn.BIT.Pn7 = 0;
646  sleep(10);
647  PORT2.Pn.BIT.Pn7 = 1;
648  sleep(10);
649 #endif
650 }
651 
652 
653 /**
654  * @brief Initialize DMA descriptor lists
655  * @param[in] interface Underlying network interface
656  **/
657 
659 {
660  uint_t i;
661 
662  //Initialize TX descriptors
663  for(i = 0; i < RZA1_ETH_TX_BUFFER_COUNT; i++)
664  {
665  //The descriptor is initially owned by the application
666  txDmaDesc[i].td0 = 0;
667  //Transmit buffer length
668  txDmaDesc[i].td1 = 0;
669  //Transmit buffer address
670  txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
671  //Clear padding field
672  txDmaDesc[i].padding = 0;
673  }
674 
675  //Mark the last descriptor entry with the TDLE flag
676  txDmaDesc[i - 1].td0 |= ETHER_TD0_TDLE;
677  //Initialize TX descriptor index
678  txIndex = 0;
679 
680  //Initialize RX descriptors
681  for(i = 0; i < RZA1_ETH_RX_BUFFER_COUNT; i++)
682  {
683  //The descriptor is initially owned by the DMA
684  rxDmaDesc[i].rd0 = ETHER_RD0_RACT;
685  //Receive buffer length
687  //Receive buffer address
688  rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
689  //Clear padding field
690  rxDmaDesc[i].padding = 0;
691  }
692 
693  //Mark the last descriptor entry with the RDLE flag
694  rxDmaDesc[i - 1].rd0 |= ETHER_RD0_RDLE;
695  //Initialize RX descriptor index
696  rxIndex = 0;
697 
698  //Address of the first TX descriptor
699  ETHER.TDLAR0 = (uint32_t) &txDmaDesc[0];
700  ETHER.TDFAR0 = (uint32_t) &txDmaDesc[0];
701  //Address of the last TX descriptor
702  ETHER.TDFXR0 = (uint32_t) &txDmaDesc[RZA1_ETH_TX_BUFFER_COUNT - 1];
703  //Set TDLF flag
704  ETHER.TDFFR0 = ETHER_TDFFR_TDLF;
705 
706  //Address of the first RX descriptor
707  ETHER.RDLAR0 = (uint32_t) &rxDmaDesc[0];
708  ETHER.RDFAR0 = (uint32_t) &rxDmaDesc[0];
709  //Address of the last RX descriptor
710  ETHER.RDFXR0 = (uint32_t) &rxDmaDesc[RZA1_ETH_RX_BUFFER_COUNT - 1];
711  //Set RDLF flag
712  ETHER.RDFFR0 = ETHER_RDFFR0_RDLF;
713 }
714 
715 
716 /**
717  * @brief RZ/A1 Ethernet MAC timer handler
718  *
719  * This routine is periodically called by the TCP/IP stack to handle periodic
720  * operations such as polling the link state
721  *
722  * @param[in] interface Underlying network interface
723  **/
724 
725 void rza1EthTick(NetInterface *interface)
726 {
727  //Valid Ethernet PHY or switch driver?
728  if(interface->phyDriver != NULL)
729  {
730  //Handle periodic operations
731  interface->phyDriver->tick(interface);
732  }
733  else if(interface->switchDriver != NULL)
734  {
735  //Handle periodic operations
736  interface->switchDriver->tick(interface);
737  }
738  else
739  {
740  //Just for sanity
741  }
742 }
743 
744 
745 /**
746  * @brief Enable interrupts
747  * @param[in] interface Underlying network interface
748  **/
749 
751 {
752  //Enable Ethernet MAC interrupts
753  R_INTC_Enable(INTC_ID_ETHERI);
754 
755  //Valid Ethernet PHY or switch driver?
756  if(interface->phyDriver != NULL)
757  {
758  //Enable Ethernet PHY interrupts
759  interface->phyDriver->enableIrq(interface);
760  }
761  else if(interface->switchDriver != NULL)
762  {
763  //Enable Ethernet switch interrupts
764  interface->switchDriver->enableIrq(interface);
765  }
766  else
767  {
768  //Just for sanity
769  }
770 }
771 
772 
773 /**
774  * @brief Disable interrupts
775  * @param[in] interface Underlying network interface
776  **/
777 
779 {
780  //Disable Ethernet MAC interrupts
781  R_INTC_Disable(INTC_ID_ETHERI);
782 
783  //Valid Ethernet PHY or switch driver?
784  if(interface->phyDriver != NULL)
785  {
786  //Disable Ethernet PHY interrupts
787  interface->phyDriver->disableIrq(interface);
788  }
789  else if(interface->switchDriver != NULL)
790  {
791  //Disable Ethernet switch interrupts
792  interface->switchDriver->disableIrq(interface);
793  }
794  else
795  {
796  //Just for sanity
797  }
798 }
799 
800 
801 /**
802  * @brief RZ/A1 Ethernet MAC interrupt service routine
803  * @param[in] intSense Unused parameter
804  **/
805 
806 void rza1EthIrqHandler(uint32_t intSense)
807 {
808  bool_t flag;
809  uint32_t status;
810 
811  //Interrupt service routine prologue
812  osEnterIsr();
813 
814  //This flag will be set if a higher priority task must be woken
815  flag = FALSE;
816 
817  //Read interrupt status register
818  status = ETHER.EESR0;
819 
820  //Packet transmitted?
821  if((status & ETHER_EESR0_TWB) != 0)
822  {
823  //Clear TWB interrupt flag
824  ETHER.EESR0 = ETHER_EESR0_TWB;
825 
826  //Check whether the TX buffer is available for writing
827  if((txDmaDesc[txIndex].td0 & ETHER_TD0_TACT) == 0)
828  {
829  //Notify the TCP/IP stack that the transmitter is ready to send
830  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
831  }
832  }
833 
834  //Packet received?
835  if((status & ETHER_EESR0_FR) != 0)
836  {
837  //Disable FR interrupts
838  ETHER.EESIPR0 &= ~ETHER_EESIPR0_FRIP;
839 
840  //Set event flag
841  nicDriverInterface->nicEvent = TRUE;
842  //Notify the TCP/IP stack of the event
843  flag |= osSetEventFromIsr(&netEvent);
844  }
845 
846  //Interrupt service routine epilogue
847  osExitIsr(flag);
848 }
849 
850 
851 /**
852  * @brief RZ/A1 Ethernet MAC event handler
853  * @param[in] interface Underlying network interface
854  **/
855 
857 {
858  error_t error;
859 
860  //Packet received?
861  if((ETHER.EESR0 & ETHER_EESR0_FR) != 0)
862  {
863  //Clear FR interrupt flag
864  ETHER.EESR0 = ETHER_EESR0_FR;
865 
866  //Process all pending packets
867  do
868  {
869  //Read incoming packet
870  error = rza1EthReceivePacket(interface);
871 
872  //No more data in the receive buffer?
873  } while(error != ERROR_BUFFER_EMPTY);
874  }
875 
876  //Re-enable EDMAC interrupts
877  ETHER.EESIPR0 = ETHER_EESIPR0_TWBIP | ETHER_EESIPR0_FRIP;
878 }
879 
880 
881 /**
882  * @brief Send a packet
883  * @param[in] interface Underlying network interface
884  * @param[in] buffer Multi-part buffer containing the data to send
885  * @param[in] offset Offset to the first data byte
886  * @param[in] ancillary Additional options passed to the stack along with
887  * the packet
888  * @return Error code
889  **/
890 
892  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
893 {
894  //Retrieve the length of the packet
895  size_t length = netBufferGetLength(buffer) - offset;
896 
897  //Check the frame length
899  {
900  //The transmitter can accept another packet
901  osSetEvent(&interface->nicTxEvent);
902  //Report an error
903  return ERROR_INVALID_LENGTH;
904  }
905 
906  //Make sure the current buffer is available for writing
907  if((txDmaDesc[txIndex].td0 & ETHER_TD0_TACT) != 0)
908  {
909  return ERROR_FAILURE;
910  }
911 
912  //Copy user data to the transmit buffer
913  netBufferRead(txBuffer[txIndex], buffer, offset, length);
914 
915  //Write the number of bytes to send
916  txDmaDesc[txIndex].td1 = (length << 16) & ETHER_TD1_TDL;
917 
918  //Check current index
919  if(txIndex < (RZA1_ETH_TX_BUFFER_COUNT - 1))
920  {
921  //Give the ownership of the descriptor to the DMA engine
922  txDmaDesc[txIndex].td0 = ETHER_TD0_TACT | ETHER_TD0_TFP_SOF |
924 
925  //Point to the next descriptor
926  txIndex++;
927  }
928  else
929  {
930  //Give the ownership of the descriptor to the DMA engine
931  txDmaDesc[txIndex].td0 = ETHER_TD0_TACT | ETHER_TD0_TDLE |
933 
934  //Wrap around
935  txIndex = 0;
936  }
937 
938  //Instruct the DMA to poll the transmit descriptor list
939  ETHER.EDTRR0 = ETHER_EDTRR0_TR;
940 
941  //Check whether the next buffer is available for writing
942  if((txDmaDesc[txIndex].td0 & ETHER_TD0_TACT) == 0)
943  {
944  //The transmitter can accept another packet
945  osSetEvent(&interface->nicTxEvent);
946  }
947 
948  //Successful write operation
949  return NO_ERROR;
950 }
951 
952 
953 /**
954  * @brief Receive a packet
955  * @param[in] interface Underlying network interface
956  * @return Error code
957  **/
959 {
960  static uint32_t temp[RZA1_ETH_RX_BUFFER_SIZE / 4];
961  error_t error;
962  size_t n;
963  NetRxAncillary ancillary;
964 
965  //Current buffer available for reading?
966  if((rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RACT) == 0)
967  {
968  //SOF and EOF flags should be set
969  if((rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RFP_SOF) != 0 &&
970  (rxDmaDesc[rxIndex].rd0 & ETHER_RD0_RFP_EOF) != 0)
971  {
972  //Make sure no error occurred
973  if((rxDmaDesc[rxIndex].rd0 & (ETHER_RD0_RFS_MASK & ~ETHER_RD0_RFS_RMAF)) == 0)
974  {
975  //Retrieve the length of the frame
976  n = rxDmaDesc[rxIndex].rd1 & ETHER_RD1_RDL;
977  //Limit the number of data to read
979 
980  //Copy data from the receive buffer
981  osMemcpy(temp, rxBuffer[rxIndex], n);
982 
983  //Additional options can be passed to the stack along with the packet
984  ancillary = NET_DEFAULT_RX_ANCILLARY;
985 
986  //Pass the packet to the upper layer
987  nicProcessPacket(interface, (uint8_t *) temp, n, &ancillary);
988 
989  //Valid packet received
990  error = NO_ERROR;
991  }
992  else
993  {
994  //The received packet contains an error
995  error = ERROR_INVALID_PACKET;
996  }
997  }
998  else
999  {
1000  //The packet is not valid
1001  error = ERROR_INVALID_PACKET;
1002  }
1003 
1004  //Check current index
1005  if(rxIndex < (RZA1_ETH_RX_BUFFER_COUNT - 1))
1006  {
1007  //Give the ownership of the descriptor back to the DMA
1008  rxDmaDesc[rxIndex].rd0 = ETHER_RD0_RACT;
1009  //Point to the next descriptor
1010  rxIndex++;
1011  }
1012  else
1013  {
1014  //Give the ownership of the descriptor back to the DMA
1015  rxDmaDesc[rxIndex].rd0 = ETHER_RD0_RACT | ETHER_RD0_RDLE;
1016  //Wrap around
1017  rxIndex = 0;
1018  }
1019 
1020  //Instruct the DMA to poll the receive descriptor list
1021  ETHER.EDRRR0 = ETHER_EDRRR0_RR;
1022  }
1023  else
1024  {
1025  //No more data in the receive buffer
1026  error = ERROR_BUFFER_EMPTY;
1027  }
1028 
1029  //Return status code
1030  return error;
1031 }
1032 
1033 
1034 /**
1035  * @brief Configure MAC address filtering
1036  * @param[in] interface Underlying network interface
1037  * @return Error code
1038  **/
1039 
1041 {
1042  uint_t i;
1043  volatile uint32_t *addrHigh;
1044  volatile uint32_t *addrLow;
1045  MacFilterEntry *entry;
1046 
1047  //Debug message
1048  TRACE_DEBUG("Updating MAC filter...\r\n");
1049 
1050  //Set the upper 32 bits of the MAC address
1051  ETHER.MAHR0 = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
1052  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
1053 
1054  //Set the lower 16 bits of the MAC address
1055  ETHER.MALR0 = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
1056 
1057  //The MAC address filter contains the list of MAC addresses to accept
1058  //when receiving an Ethernet frame
1059  for(i = 0; i < MAC_ADDR_FILTER_SIZE && i < 32; i++)
1060  {
1061  //Point to the current entry
1062  entry = &interface->macAddrFilter[i];
1063 
1064  //Valid entry?
1065  if(entry->refCount > 0)
1066  {
1067  //Debug message
1068  TRACE_DEBUG(" %s\r\n", macAddrToString(&entry->addr, NULL));
1069 
1070  //Point to the CAM entry registers
1071  addrHigh = &ETHER.TSU_ADRH0 + 2 * i;
1072  addrLow = &ETHER.TSU_ADRL0 + 2 * i;
1073 
1074  //The contents of the CAM entry table registers cannot be
1075  //modified while the ADSBSY flag is set
1076  while((ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY) != 0)
1077  {
1078  }
1079 
1080  //Set the upper 32 bits of the MAC address
1081  *addrHigh = (entry->addr.b[0] << 24) | (entry->addr.b[1] << 16) |
1082  (entry->addr.b[2] << 8) | entry->addr.b[3];
1083 
1084  //Wait for the ADSBSY flag to be cleared
1085  while((ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY) != 0)
1086  {
1087  }
1088 
1089  //Set the lower 16 bits of the MAC address
1090  *addrLow = (entry->addr.b[4] << 8) | entry->addr.b[5];
1091 
1092  //Enable the CAM entry
1093  ETHER.TSU_TEN |= 1 << (31 - i);
1094  }
1095  else
1096  {
1097  //Disable the CAM entry
1098  ETHER.TSU_TEN &= ~(1 << (31 - i));
1099  }
1100  }
1101 
1102  //Successful processing
1103  return NO_ERROR;
1104 }
1105 
1106 
1107 /**
1108  * @brief Adjust MAC configuration parameters for proper operation
1109  * @param[in] interface Underlying network interface
1110  * @return Error code
1111  **/
1112 
1114 {
1115  uint32_t mode;
1116 
1117  //Read EMAC mode register
1118  mode = ETHER.ECMR0;
1119 
1120  //Half-duplex or full-duplex mode?
1121  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
1122  {
1123  mode |= ETHER_ECMR0_DM;
1124  }
1125  else
1126  {
1127  mode &= ~ETHER_ECMR0_DM;
1128  }
1129 
1130  //Update EMAC mode register
1131  ETHER.ECMR0 = mode;
1132 
1133  //Successful processing
1134  return NO_ERROR;
1135 }
1136 
1137 
1138 /**
1139  * @brief Write PHY register
1140  * @param[in] opcode Access type (2 bits)
1141  * @param[in] phyAddr PHY address (5 bits)
1142  * @param[in] regAddr Register address (5 bits)
1143  * @param[in] data Register value
1144  **/
1145 
1146 void rza1EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
1147  uint8_t regAddr, uint16_t data)
1148 {
1149  //Synchronization pattern
1151  //Start of frame
1153  //Set up a write operation
1154  rza1EthWriteSmi(opcode, 2);
1155  //Write PHY address
1156  rza1EthWriteSmi(phyAddr, 5);
1157  //Write register address
1159  //Turnaround
1160  rza1EthWriteSmi(SMI_TA, 2);
1161  //Write register value
1162  rza1EthWriteSmi(data, 16);
1163  //Release MDIO
1164  rza1EthReadSmi(1);
1165 }
1166 
1167 
1168 /**
1169  * @brief Read PHY register
1170  * @param[in] opcode Access type (2 bits)
1171  * @param[in] phyAddr PHY address (5 bits)
1172  * @param[in] regAddr Register address (5 bits)
1173  * @return Register value
1174  **/
1175 
1176 uint16_t rza1EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
1177  uint8_t regAddr)
1178 {
1179  uint16_t data;
1180 
1181  //Synchronization pattern
1183  //Start of frame
1185  //Set up a read operation
1186  rza1EthWriteSmi(opcode, 2);
1187  //Write PHY address
1188  rza1EthWriteSmi(phyAddr, 5);
1189  //Write register address
1191  //Turnaround to avoid contention
1192  rza1EthReadSmi(1);
1193  //Read register value
1194  data = rza1EthReadSmi(16);
1195  //Force the PHY to release the MDIO pin
1196  rza1EthReadSmi(1);
1197 
1198  //Return PHY register contents
1199  return data;
1200 }
1201 
1202 
1203 /**
1204  * @brief SMI write operation
1205  * @param[in] data Raw data to be written
1206  * @param[in] length Number of bits to be written
1207  **/
1208 
1210 {
1211  //Skip the most significant bits since they are meaningless
1212  data <<= 32 - length;
1213 
1214  //Configure MDIO as an output
1215  ETHER.PIR0 |= ETHER_PIR0_MMD;
1216 
1217  //Write the specified number of bits
1218  while(length--)
1219  {
1220  //Write MDIO
1221  if((data & 0x80000000) != 0)
1222  {
1223  ETHER.PIR0 |= ETHER_PIR0_MDO;
1224  }
1225  else
1226  {
1227  ETHER.PIR0 &= ~ETHER_PIR0_MDO;
1228  }
1229 
1230  //Assert MDC
1231  usleep(1);
1232  ETHER.PIR0 |= ETHER_PIR0_MDC;
1233  //Deassert MDC
1234  usleep(1);
1235  ETHER.PIR0 &= ~ETHER_PIR0_MDC;
1236 
1237  //Rotate data
1238  data <<= 1;
1239  }
1240 }
1241 
1242 
1243 /**
1244  * @brief SMI read operation
1245  * @param[in] length Number of bits to be read
1246  * @return Data resulting from the MDIO read operation
1247  **/
1248 
1250 {
1251  uint32_t data = 0;
1252 
1253  //Configure MDIO as an input
1254  ETHER.PIR0 &= ~ETHER_PIR0_MMD;
1255 
1256  //Read the specified number of bits
1257  while(length--)
1258  {
1259  //Rotate data
1260  data <<= 1;
1261 
1262  //Assert MDC
1263  ETHER.PIR0 |= ETHER_PIR0_MDC;
1264  usleep(1);
1265  //Deassert MDC
1266  ETHER.PIR0 &= ~ETHER_PIR0_MDC;
1267  usleep(1);
1268 
1269  //Check MDIO state
1270  if((ETHER.PIR0 & ETHER_PIR0_MDI) != 0)
1271  {
1272  data |= 0x01;
1273  }
1274  }
1275 
1276  //Return the received data
1277  return data;
1278 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void rza1EthWriteSmi(uint32_t data, uint_t length)
SMI write operation.
#define usleep(delay)
Definition: os_port.h:303
#define ETHER_EESR0_FR
Transmit DMA descriptor.
uint8_t opcode
Definition: dns_common.h:188
int bool_t
Definition: compiler_port.h:53
#define netEvent
Definition: net_legacy.h:196
#define ETHER_EDRRR0_RR
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define ETHER_PIR0_MDC
#define ETHER_TDFFR_TDLF
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
#define ETHER_ECMR0_RE
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
#define ETHER_TSU_ADSBSY_ADSBSY
uint8_t data[]
Definition: ethernet.h:222
#define sleep(delay)
Definition: os_port.h:307
#define ETHER_RD0_RFP_EOF
#define ETHER_FDR0_TFD_2048
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
#define ETHER_RDFFR0_RDLF
#define ETHER_RD0_RFP_SOF
error_t rza1EthInit(NetInterface *interface)
RZ/A1 Ethernet MAC initialization.
#define ETHER_RD0_RACT
#define SMI_TA
Definition: nic.h:68
#define ETHER_TD0_TFP_EOF
#define ETHER_RMCR0_RNC
#define ETHER_EDTRR0_TR
void rza1EthEventHandler(NetInterface *interface)
RZ/A1 Ethernet MAC event handler.
#define SMI_START
Definition: nic.h:64
#define ETHER_EDSR0_ENT
#define ETHER_ARSTR_ARST
#define ETHER_TD0_TACT
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:392
error_t rza1EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
#define osExitIsr(flag)
#define ETHER_PIR0_MDO
error_t rza1EthReceivePacket(NetInterface *interface)
Receive a packet.
#define ETHER_FCFTR0_RFD_2048
error_t rza1EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define RZA1_ETH_TX_BUFFER_SIZE
#define FALSE
Definition: os_port.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
void rza1EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define ETHER_FDR0_RFD_2048
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:104
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
char_t * macAddrToString(const MacAddr *macAddr, char_t *str)
Convert a MAC address to a dash delimited string.
Definition: ethernet.c:919
error_t rza1EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define txBuffer
__weak_func void rza1EthInitGpio(NetInterface *interface)
GPIO configuration.
#define NetRxAncillary
Definition: net_misc.h:40
@ ERROR_INVALID_PACKET
Definition: error.h:140
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:263
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
#define RZA1_ETH_RAM_SECTION
#define ETHER_EESIPR0_TWBIP
#define ETHER_TD0_TWBI
#define NetTxAncillary
Definition: net_misc.h:36
#define ETHER_EDMR0_SWRR
#define ETHER_RD0_RFS_MASK
void rza1EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define ETHER_TD0_TDLE
#define ETHER_TD0_TFP_SOF
#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 ETHER_FCFTR0_RFF_8
#define ETHER_RD0_RDLE
#define MIN(a, b)
Definition: os_port.h:63
Renesas RZ/A1 Ethernet MAC driver.
uint16_t rza1EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define rxBuffer
void rza1EthTick(NetInterface *interface)
RZ/A1 Ethernet MAC timer handler.
#define ETHER_PIR0_MDI
#define ETHER_ECMR0_MCT
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define ETHER_EDMR0_DE
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:116
uint8_t n
MAC filter table entry.
Definition: ethernet.h:262
#define ETHER_EDMR0_DL_16
void rza1EthIrqHandler(uint32_t intSense)
RZ/A1 Ethernet MAC interrupt service routine.
#define osEnterIsr()
#define RZA1_ETH_RX_BUFFER_COUNT
#define RZA1_ETH_TX_BUFFER_COUNT
#define ETHER_ECMR0_TE
#define RZA1_ETH_RX_BUFFER_SIZE
#define ETHER_EESR0_TWB
#define rxDmaDesc
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define ETHER_RD1_RDL
const NicDriver rza1EthDriver
RZ/A1 Ethernet MAC driver.
#define ETHER_TD1_TDL
#define txDmaDesc
Receive DMA descriptor.
uint32_t rza1EthReadSmi(uint_t length)
SMI read operation.
#define ETHER_EDSR0_ENR
#define SMI_SYNC
Definition: nic.h:63
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
#define ETHER_PIR0_MMD
NIC driver.
Definition: nic.h:286
#define ETHER_RD1_RBL
void rza1EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define ETHER_RD0_RFS_RMAF
void rza1EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define ETHER_EESIPR0_FRIP
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define ETHER_ECMR0_DM
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define ETHER_EDMR0_SWRT
#define RZA1_ETH_IRQ_PRIORITY